Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/lower.rs')
-rw-r--r--crates/hir-ty/src/lower.rs331
1 files changed, 208 insertions, 123 deletions
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index c7ed68448b..e3a92e52f6 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -34,6 +34,7 @@ use hir_def::{
resolver::{HasResolver, LifetimeNs, Resolver, TypeNs},
type_ref::{
ConstRef, LifetimeRef, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
+ TypeRefId, TypesMap, TypesSourceMap,
},
AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId,
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstLoc, ItemContainerId,
@@ -41,7 +42,6 @@ use hir_def::{
TypeOwnerId, UnionId, VariantId,
};
use hir_expand::{name::Name, ExpandResult};
-use intern::Interned;
use la_arena::{Arena, ArenaMap};
use rustc_hash::FxHashSet;
use rustc_pattern_analysis::Captures;
@@ -122,6 +122,11 @@ pub struct TyLoweringContext<'a> {
pub db: &'a dyn HirDatabase,
resolver: &'a Resolver,
generics: OnceCell<Option<Generics>>,
+ types_map: &'a TypesMap,
+ /// If this is set, that means we're in a context of a freshly expanded macro, and that means
+ /// we should not use `TypeRefId` in diagnostics because the caller won't have the `TypesMap`,
+ /// instead we need to put `TypeSource` from the source map.
+ types_source_map: Option<&'a TypesSourceMap>,
in_binders: DebruijnIndex,
// FIXME: Should not be an `Option` but `Resolver` currently does not return owners in all cases
// where expected
@@ -138,13 +143,20 @@ pub struct TyLoweringContext<'a> {
}
impl<'a> TyLoweringContext<'a> {
- pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver, owner: TypeOwnerId) -> Self {
- Self::new_maybe_unowned(db, resolver, Some(owner))
+ pub fn new(
+ db: &'a dyn HirDatabase,
+ resolver: &'a Resolver,
+ types_map: &'a TypesMap,
+ owner: TypeOwnerId,
+ ) -> Self {
+ Self::new_maybe_unowned(db, resolver, types_map, None, Some(owner))
}
pub fn new_maybe_unowned(
db: &'a dyn HirDatabase,
resolver: &'a Resolver,
+ types_map: &'a TypesMap,
+ types_source_map: Option<&'a TypesSourceMap>,
owner: Option<TypeOwnerId>,
) -> Self {
let impl_trait_mode = ImplTraitLoweringState::Disallowed;
@@ -154,6 +166,8 @@ impl<'a> TyLoweringContext<'a> {
db,
resolver,
generics: OnceCell::new(),
+ types_map,
+ types_source_map,
owner,
in_binders,
impl_trait_mode,
@@ -201,6 +215,16 @@ impl<'a> TyLoweringContext<'a> {
pub fn with_type_param_mode(self, type_param_mode: ParamLoweringMode) -> Self {
Self { type_param_mode, ..self }
}
+
+ pub fn impl_trait_mode(&mut self, impl_trait_mode: ImplTraitLoweringMode) -> &mut Self {
+ self.impl_trait_mode = ImplTraitLoweringState::new(impl_trait_mode);
+ self
+ }
+
+ pub fn type_param_mode(&mut self, type_param_mode: ParamLoweringMode) -> &mut Self {
+ self.type_param_mode = type_param_mode;
+ self
+ }
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -230,7 +254,7 @@ pub enum ParamLoweringMode {
}
impl<'a> TyLoweringContext<'a> {
- pub fn lower_ty(&self, type_ref: &TypeRef) -> Ty {
+ pub fn lower_ty(&self, type_ref: TypeRefId) -> Ty {
self.lower_ty_ext(type_ref).0
}
@@ -254,12 +278,13 @@ impl<'a> TyLoweringContext<'a> {
.as_ref()
}
- pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
+ pub fn lower_ty_ext(&self, type_ref_id: TypeRefId) -> (Ty, Option<TypeNs>) {
let mut res = None;
+ let type_ref = &self.types_map[type_ref_id];
let ty = match type_ref {
TypeRef::Never => TyKind::Never.intern(Interner),
TypeRef::Tuple(inner) => {
- let inner_tys = inner.iter().map(|tr| self.lower_ty(tr));
+ let inner_tys = inner.iter().map(|&tr| self.lower_ty(tr));
TyKind::Tuple(inner_tys.len(), Substitution::from_iter(Interner, inner_tys))
.intern(Interner)
}
@@ -268,38 +293,43 @@ impl<'a> TyLoweringContext<'a> {
res = res_;
ty
}
- TypeRef::RawPtr(inner, mutability) => {
+ &TypeRef::RawPtr(inner, mutability) => {
let inner_ty = self.lower_ty(inner);
- TyKind::Raw(lower_to_chalk_mutability(*mutability), inner_ty).intern(Interner)
+ TyKind::Raw(lower_to_chalk_mutability(mutability), inner_ty).intern(Interner)
}
- TypeRef::Array(inner, len) => {
- let inner_ty = self.lower_ty(inner);
- let const_len = self.lower_const(len, TyBuilder::usize());
+ TypeRef::Array(array) => {
+ let inner_ty = self.lower_ty(array.ty);
+ let const_len = self.lower_const(&array.len, TyBuilder::usize());
TyKind::Array(inner_ty, const_len).intern(Interner)
}
- TypeRef::Slice(inner) => {
+ &TypeRef::Slice(inner) => {
let inner_ty = self.lower_ty(inner);
TyKind::Slice(inner_ty).intern(Interner)
}
- TypeRef::Reference(inner, lifetime, mutability) => {
- let inner_ty = self.lower_ty(inner);
+ TypeRef::Reference(ref_) => {
+ let inner_ty = self.lower_ty(ref_.ty);
// FIXME: It should infer the eldided lifetimes instead of stubbing with static
- let lifetime =
- lifetime.as_ref().map_or_else(error_lifetime, |lr| self.lower_lifetime(lr));
- TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
+ let lifetime = ref_
+ .lifetime
+ .as_ref()
+ .map_or_else(error_lifetime, |lr| self.lower_lifetime(lr));
+ TyKind::Ref(lower_to_chalk_mutability(ref_.mutability), lifetime, inner_ty)
.intern(Interner)
}
TypeRef::Placeholder => TyKind::Error.intern(Interner),
- &TypeRef::Fn(ref params, variadic, is_unsafe, ref abi) => {
+ TypeRef::Fn(fn_) => {
let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
- Substitution::from_iter(Interner, params.iter().map(|(_, tr)| ctx.lower_ty(tr)))
+ Substitution::from_iter(
+ Interner,
+ fn_.params().iter().map(|&(_, tr)| ctx.lower_ty(tr)),
+ )
});
TyKind::Function(FnPointer {
num_binders: 0, // FIXME lower `for<'a> fn()` correctly
sig: FnSig {
- abi: abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol),
- safety: if is_unsafe { Safety::Unsafe } else { Safety::Safe },
- variadic,
+ abi: fn_.abi().as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol),
+ safety: if fn_.is_unsafe() { Safety::Unsafe } else { Safety::Safe },
+ variadic: fn_.is_varargs(),
},
substitution: FnSubst(substs),
})
@@ -351,8 +381,8 @@ impl<'a> TyLoweringContext<'a> {
ImplTraitLoweringState::Param(counter) => {
let idx = counter.get();
// Count the number of `impl Trait` things that appear within our bounds.
- // Since t hose have been emitted as implicit type args already.
- counter.set(idx + count_impl_traits(type_ref) as u16);
+ // Since those have been emitted as implicit type args already.
+ counter.set(idx + self.count_impl_traits(type_ref_id) as u16);
let kind = self
.generics()
.expect("param impl trait lowering must be in a generic def")
@@ -376,7 +406,7 @@ impl<'a> TyLoweringContext<'a> {
let idx = counter.get();
// Count the number of `impl Trait` things that appear within our bounds.
// Since t hose have been emitted as implicit type args already.
- counter.set(idx + count_impl_traits(type_ref) as u16);
+ counter.set(idx + self.count_impl_traits(type_ref_id) as u16);
let kind = self
.generics()
.expect("variable impl trait lowering must be in a generic def")
@@ -432,12 +462,40 @@ impl<'a> TyLoweringContext<'a> {
match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call, resolver)
{
Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
- let ctx = expander.ctx(self.db.upcast());
+ let (mut types_map, mut types_source_map) =
+ (TypesMap::default(), TypesSourceMap::default());
+
+ let ctx = expander.ctx(
+ self.db.upcast(),
+ &mut types_map,
+ &mut types_source_map,
+ );
// FIXME: Report syntax errors in expansion here
let type_ref = TypeRef::from_ast(&ctx, expanded.tree());
drop(expander);
- let ty = self.lower_ty(&type_ref);
+
+ // FIXME: That may be better served by mutating `self` then restoring, but this requires
+ // making it `&mut self`.
+ let inner_ctx = TyLoweringContext {
+ db: self.db,
+ resolver: self.resolver,
+ generics: self.generics.clone(),
+ types_map: &types_map,
+ types_source_map: Some(&types_source_map),
+ in_binders: self.in_binders,
+ owner: self.owner,
+ type_param_mode: self.type_param_mode,
+ impl_trait_mode: self.impl_trait_mode.take(),
+ expander: RefCell::new(self.expander.take()),
+ unsized_types: RefCell::new(self.unsized_types.take()),
+ };
+
+ let ty = inner_ctx.lower_ty(type_ref);
+
+ self.impl_trait_mode.swap(&inner_ctx.impl_trait_mode);
+ *self.expander.borrow_mut() = inner_ctx.expander.into_inner();
+ *self.unsized_types.borrow_mut() = inner_ctx.unsized_types.into_inner();
self.expander.borrow_mut().as_mut().unwrap().exit(mark);
Some(ty)
@@ -463,7 +521,8 @@ impl<'a> TyLoweringContext<'a> {
/// This is only for `generic_predicates_for_param`, where we can't just
/// lower the self types of the predicates since that could lead to cycles.
/// So we just check here if the `type_ref` resolves to a generic param, and which.
- fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeOrConstParamId> {
+ fn lower_ty_only_param(&self, type_ref: TypeRefId) -> Option<TypeOrConstParamId> {
+ let type_ref = &self.types_map[type_ref];
let path = match type_ref {
TypeRef::Path(path) => path,
_ => return None,
@@ -663,7 +722,7 @@ impl<'a> TyLoweringContext<'a> {
if matches!(resolution, TypeNs::TraitId(_)) && remaining_index.is_none() {
// trait object type without dyn
let bound = TypeBound::Path(path.clone(), TraitBoundModifier::None);
- let ty = self.lower_dyn_trait(&[Interned::new(bound)]);
+ let ty = self.lower_dyn_trait(&[bound]);
return (ty, None);
}
@@ -864,7 +923,7 @@ impl<'a> TyLoweringContext<'a> {
assert!(matches!(id, GenericParamId::TypeParamId(_)));
had_explicit_args = true;
if let GenericArg::Type(ty) = &args[0] {
- substs.push(self.lower_ty(ty).cast(Interner));
+ substs.push(self.lower_ty(*ty).cast(Interner));
}
}
} else {
@@ -901,6 +960,7 @@ impl<'a> TyLoweringContext<'a> {
id,
arg,
&mut (),
+ self.types_map,
|_, type_ref| self.lower_ty(type_ref),
|_, const_ref, ty| self.lower_const(const_ref, ty),
|_, lifetime_ref| self.lower_lifetime(lifetime_ref),
@@ -998,7 +1058,7 @@ impl<'a> TyLoweringContext<'a> {
WherePredicate::ForLifetime { target, bound, .. }
| WherePredicate::TypeBound { target, bound } => {
let self_ty = match target {
- WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
+ WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(*type_ref),
&WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
let param_id = hir_def::TypeOrConstParamId { parent: def, local_id };
match self.type_param_mode {
@@ -1029,12 +1089,12 @@ impl<'a> TyLoweringContext<'a> {
pub(crate) fn lower_type_bound(
&'a self,
- bound: &'a Interned<TypeBound>,
+ bound: &'a TypeBound,
self_ty: Ty,
ignore_bindings: bool,
) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
let mut trait_ref = None;
- let clause = match bound.as_ref() {
+ let clause = match bound {
TypeBound::Path(path, TraitBoundModifier::None) => {
trait_ref = self.lower_trait_ref_from_path(path, self_ty);
trait_ref.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
@@ -1067,7 +1127,7 @@ impl<'a> TyLoweringContext<'a> {
lifetime,
})))
}
- TypeBound::Error => None,
+ TypeBound::Use(_) | TypeBound::Error => None,
};
clause.into_iter().chain(
trait_ref
@@ -1079,14 +1139,15 @@ impl<'a> TyLoweringContext<'a> {
fn assoc_type_bindings_from_type_bound(
&'a self,
- bound: &'a Interned<TypeBound>,
+ bound: &'a TypeBound,
trait_ref: TraitRef,
) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
- let last_segment = match bound.as_ref() {
+ let last_segment = match bound {
TypeBound::Path(path, TraitBoundModifier::None) | TypeBound::ForLifetime(_, path) => {
path.segments().last()
}
TypeBound::Path(_, TraitBoundModifier::Maybe)
+ | TypeBound::Use(_)
| TypeBound::Error
| TypeBound::Lifetime(_) => None,
};
@@ -1110,7 +1171,7 @@ impl<'a> TyLoweringContext<'a> {
// this point (`super_trait_ref.substitution`).
let substitution = self.substs_from_path_segment(
// FIXME: This is hack. We shouldn't really build `PathSegment` directly.
- PathSegment { name: &binding.name, args_and_bindings: binding.args.as_deref() },
+ PathSegment { name: &binding.name, args_and_bindings: binding.args.as_ref() },
Some(associated_ty.into()),
false, // this is not relevant
Some(super_trait_ref.self_type_parameter(Interner)),
@@ -1130,8 +1191,8 @@ impl<'a> TyLoweringContext<'a> {
let mut predicates: SmallVec<[_; 1]> = SmallVec::with_capacity(
binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
);
- if let Some(type_ref) = &binding.type_ref {
- match (type_ref, &self.impl_trait_mode) {
+ if let Some(type_ref) = binding.type_ref {
+ match (&self.types_map[type_ref], &self.impl_trait_mode) {
(TypeRef::ImplTrait(_), ImplTraitLoweringState::Disallowed) => (),
(
_,
@@ -1178,6 +1239,8 @@ impl<'a> TyLoweringContext<'a> {
let mut ext = TyLoweringContext::new_maybe_unowned(
self.db,
self.resolver,
+ self.types_map,
+ self.types_source_map,
self.owner,
)
.with_type_param_mode(self.type_param_mode);
@@ -1215,7 +1278,7 @@ impl<'a> TyLoweringContext<'a> {
})
}
- fn lower_dyn_trait(&self, bounds: &[Interned<TypeBound>]) -> Ty {
+ fn lower_dyn_trait(&self, bounds: &[TypeBound]) -> Ty {
let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
// INVARIANT: The principal trait bound, if present, must come first. Others may be in any
// order but should be in the same order for the same set but possibly different order of
@@ -1313,7 +1376,7 @@ impl<'a> TyLoweringContext<'a> {
}
}
- fn lower_impl_trait(&self, bounds: &[Interned<TypeBound>], krate: CrateId) -> ImplTrait {
+ fn lower_impl_trait(&self, bounds: &[TypeBound], krate: CrateId) -> ImplTrait {
cov_mark::hit!(lower_rpit);
let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
@@ -1365,6 +1428,17 @@ impl<'a> TyLoweringContext<'a> {
None => error_lifetime(),
}
}
+
+ // FIXME: This does not handle macros!
+ fn count_impl_traits(&self, type_ref: TypeRefId) -> usize {
+ let mut count = 0;
+ TypeRef::walk(type_ref, self.types_map, &mut |type_ref| {
+ if matches!(type_ref, TypeRef::ImplTrait(_)) {
+ count += 1;
+ }
+ });
+ count
+ }
}
/// Build the signature of a callable item (function, struct or enum variant).
@@ -1385,17 +1459,6 @@ pub fn associated_type_shorthand_candidates<R>(
named_associated_type_shorthand_candidates(db, def, res, None, |name, _, id| cb(name, id))
}
-// FIXME: This does not handle macros!
-fn count_impl_traits(type_ref: &TypeRef) -> usize {
- let mut count = 0;
- type_ref.walk(&mut |type_ref| {
- if matches!(type_ref, TypeRef::ImplTrait(_)) {
- count += 1;
- }
- });
- count
-}
-
fn named_associated_type_shorthand_candidates<R>(
db: &dyn HirDatabase,
// If the type parameter is defined in an impl and we're in a method, there
@@ -1499,10 +1562,10 @@ pub(crate) fn field_types_query(
};
let generics = generics(db.upcast(), def);
let mut res = ArenaMap::default();
- let ctx = TyLoweringContext::new(db, &resolver, def.into())
+ let ctx = TyLoweringContext::new(db, &resolver, var_data.types_map(), def.into())
.with_type_param_mode(ParamLoweringMode::Variable);
for (field_id, field_data) in var_data.fields().iter() {
- res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)));
+ res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(field_data.type_ref)));
}
Arc::new(res)
}
@@ -1522,38 +1585,38 @@ pub(crate) fn generic_predicates_for_param_query(
assoc_name: Option<Name>,
) -> GenericPredicates {
let resolver = def.resolver(db.upcast());
- let ctx = if let GenericDefId::FunctionId(_) = def {
- TyLoweringContext::new(db, &resolver, def.into())
+ let mut ctx = if let GenericDefId::FunctionId(_) = def {
+ TyLoweringContext::new(db, &resolver, TypesMap::EMPTY, def.into())
.with_impl_trait_mode(ImplTraitLoweringMode::Variable)
.with_type_param_mode(ParamLoweringMode::Variable)
} else {
- TyLoweringContext::new(db, &resolver, def.into())
+ TyLoweringContext::new(db, &resolver, TypesMap::EMPTY, def.into())
.with_type_param_mode(ParamLoweringMode::Variable)
};
let generics = generics(db.upcast(), def);
// we have to filter out all other predicates *first*, before attempting to lower them
- let predicate = |(pred, &def): &(&_, _)| match pred {
+ let predicate = |pred: &_, def: &_, ctx: &TyLoweringContext<'_>| match pred {
WherePredicate::ForLifetime { target, bound, .. }
| WherePredicate::TypeBound { target, bound, .. } => {
let invalid_target = match target {
WherePredicateTypeTarget::TypeRef(type_ref) => {
- ctx.lower_ty_only_param(type_ref) != Some(param_id)
+ ctx.lower_ty_only_param(*type_ref) != Some(param_id)
}
&WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
- let target_id = TypeOrConstParamId { parent: def, local_id };
+ let target_id = TypeOrConstParamId { parent: *def, local_id };
target_id != param_id
}
};
if invalid_target {
// If this is filtered out without lowering, `?Sized` is not gathered into `ctx.unsized_types`
- if let TypeBound::Path(_, TraitBoundModifier::Maybe) = &**bound {
- ctx.lower_where_predicate(pred, &def, true).for_each(drop);
+ if let TypeBound::Path(_, TraitBoundModifier::Maybe) = bound {
+ ctx.lower_where_predicate(pred, def, true).for_each(drop);
}
return false;
}
- match &**bound {
+ match bound {
TypeBound::ForLifetime(_, path) | TypeBound::Path(path, _) => {
// Only lower the bound if the trait could possibly define the associated
// type we're looking for.
@@ -1571,18 +1634,20 @@ pub(crate) fn generic_predicates_for_param_query(
})
})
}
- TypeBound::Lifetime(_) | TypeBound::Error => false,
+ TypeBound::Use(_) | TypeBound::Lifetime(_) | TypeBound::Error => false,
}
}
WherePredicate::Lifetime { .. } => false,
};
- let mut predicates: Vec<_> = resolver
- .where_predicates_in_scope()
- .filter(predicate)
- .flat_map(|(pred, def)| {
- ctx.lower_where_predicate(pred, def, true).map(|p| make_binders(db, &generics, p))
- })
- .collect();
+ let mut predicates = Vec::new();
+ for (params, def) in resolver.all_generic_params() {
+ ctx.types_map = &params.types_map;
+ predicates.extend(
+ params.where_predicates().filter(|pred| predicate(pred, def, &ctx)).flat_map(|pred| {
+ ctx.lower_where_predicate(pred, def, true).map(|p| make_binders(db, &generics, p))
+ }),
+ );
+ }
let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
if !subst.is_empty(Interner) {
@@ -1629,23 +1694,27 @@ pub(crate) fn trait_environment_query(
def: GenericDefId,
) -> Arc<TraitEnvironment> {
let resolver = def.resolver(db.upcast());
- let ctx = if let GenericDefId::FunctionId(_) = def {
- TyLoweringContext::new(db, &resolver, def.into())
+ let mut ctx = if let GenericDefId::FunctionId(_) = def {
+ TyLoweringContext::new(db, &resolver, TypesMap::EMPTY, def.into())
.with_impl_trait_mode(ImplTraitLoweringMode::Param)
.with_type_param_mode(ParamLoweringMode::Placeholder)
} else {
- TyLoweringContext::new(db, &resolver, def.into())
+ TyLoweringContext::new(db, &resolver, TypesMap::EMPTY, def.into())
.with_type_param_mode(ParamLoweringMode::Placeholder)
};
let mut traits_in_scope = Vec::new();
let mut clauses = Vec::new();
- for (pred, def) in resolver.where_predicates_in_scope() {
- for pred in ctx.lower_where_predicate(pred, def, false) {
- if let WhereClause::Implemented(tr) = &pred.skip_binders() {
- traits_in_scope.push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
+ for (params, def) in resolver.all_generic_params() {
+ ctx.types_map = &params.types_map;
+ for pred in params.where_predicates() {
+ for pred in ctx.lower_where_predicate(pred, def, false) {
+ if let WhereClause::Implemented(tr) = pred.skip_binders() {
+ traits_in_scope
+ .push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
+ }
+ let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
+ clauses.push(program_clause.into_from_env_clause(Interner));
}
- let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
- clauses.push(program_clause.into_from_env_clause(Interner));
}
}
@@ -1724,18 +1793,20 @@ where
}
_ => (ImplTraitLoweringMode::Disallowed, ParamLoweringMode::Variable),
};
- let ctx = TyLoweringContext::new(db, &resolver, def.into())
+ let mut ctx = TyLoweringContext::new(db, &resolver, TypesMap::EMPTY, def.into())
.with_impl_trait_mode(impl_trait_lowering)
.with_type_param_mode(param_lowering);
let generics = generics(db.upcast(), def);
- let mut predicates = resolver
- .where_predicates_in_scope()
- .filter(|(pred, def)| filter(pred, def))
- .flat_map(|(pred, def)| {
- ctx.lower_where_predicate(pred, def, false).map(|p| make_binders(db, &generics, p))
- })
- .collect::<Vec<_>>();
+ let mut predicates = Vec::new();
+ for (params, def) in resolver.all_generic_params() {
+ ctx.types_map = &params.types_map;
+ predicates.extend(params.where_predicates().filter(|pred| filter(pred, def)).flat_map(
+ |pred| {
+ ctx.lower_where_predicate(pred, def, false).map(|p| make_binders(db, &generics, p))
+ },
+ ));
+ }
if generics.len() > 0 {
let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
@@ -1811,18 +1882,19 @@ pub(crate) fn generic_defaults_query(db: &dyn HirDatabase, def: GenericDefId) ->
let resolver = def.resolver(db.upcast());
let parent_start_idx = generic_params.len_self();
- let ctx = TyLoweringContext::new(db, &resolver, def.into())
+ let mut ctx = TyLoweringContext::new(db, &resolver, TypesMap::EMPTY, def.into())
.with_impl_trait_mode(ImplTraitLoweringMode::Disallowed)
.with_type_param_mode(ParamLoweringMode::Variable);
- GenericDefaults(Some(Arc::from_iter(generic_params.iter().enumerate().map(
- |(idx, (id, p))| {
+ GenericDefaults(Some(Arc::from_iter(generic_params.iter_with_types_map().enumerate().map(
+ |(idx, ((id, p), types_map))| {
+ ctx.types_map = types_map;
match p {
GenericParamDataRef::TypeParamData(p) => {
let ty = p.default.as_ref().map_or(TyKind::Error.intern(Interner), |ty| {
// Each default can only refer to previous parameters.
// Type variable default referring to parameter coming
// after it is forbidden (FIXME: report diagnostic)
- fallback_bound_vars(ctx.lower_ty(ty), idx, parent_start_idx)
+ fallback_bound_vars(ctx.lower_ty(*ty), idx, parent_start_idx)
});
crate::make_binders(db, &generic_params, ty.cast(Interner))
}
@@ -1834,7 +1906,7 @@ pub(crate) fn generic_defaults_query(db: &dyn HirDatabase, def: GenericDefId) ->
let mut val = p.default.as_ref().map_or_else(
|| unknown_const_as_generic(db.const_param_ty(id)),
|c| {
- let c = ctx.lower_const(c, ctx.lower_ty(&p.ty));
+ let c = ctx.lower_const(c, ctx.lower_ty(p.ty));
c.cast(Interner)
},
);
@@ -1874,14 +1946,14 @@ pub(crate) fn generic_defaults_recover(
fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
let data = db.function_data(def);
let resolver = def.resolver(db.upcast());
- let ctx_params = TyLoweringContext::new(db, &resolver, def.into())
+ let ctx_params = TyLoweringContext::new(db, &resolver, &data.types_map, def.into())
.with_impl_trait_mode(ImplTraitLoweringMode::Variable)
.with_type_param_mode(ParamLoweringMode::Variable);
- let params = data.params.iter().map(|tr| ctx_params.lower_ty(tr));
- let ctx_ret = TyLoweringContext::new(db, &resolver, def.into())
+ let params = data.params.iter().map(|&tr| ctx_params.lower_ty(tr));
+ let ctx_ret = TyLoweringContext::new(db, &resolver, &data.types_map, def.into())
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
.with_type_param_mode(ParamLoweringMode::Variable);
- let ret = ctx_ret.lower_ty(&data.ret_type);
+ let ret = ctx_ret.lower_ty(data.ret_type);
let generics = generics(db.upcast(), def.into());
let sig = CallableSig::from_params_and_return(
params,
@@ -1910,28 +1982,33 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
let data = db.const_data(def);
let generics = generics(db.upcast(), def.into());
let resolver = def.resolver(db.upcast());
- let ctx = TyLoweringContext::new(db, &resolver, def.into())
+ let ctx = TyLoweringContext::new(db, &resolver, &data.types_map, def.into())
.with_type_param_mode(ParamLoweringMode::Variable);
- make_binders(db, &generics, ctx.lower_ty(&data.type_ref))
+ make_binders(db, &generics, ctx.lower_ty(data.type_ref))
}
/// Build the declared type of a static.
fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
let data = db.static_data(def);
let resolver = def.resolver(db.upcast());
- let ctx = TyLoweringContext::new(db, &resolver, def.into());
+ let ctx = TyLoweringContext::new(db, &resolver, &data.types_map, def.into());
- Binders::empty(Interner, ctx.lower_ty(&data.type_ref))
+ Binders::empty(Interner, ctx.lower_ty(data.type_ref))
}
fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
let struct_data = db.struct_data(def);
let fields = struct_data.variant_data.fields();
let resolver = def.resolver(db.upcast());
- let ctx = TyLoweringContext::new(db, &resolver, AdtId::from(def).into())
- .with_type_param_mode(ParamLoweringMode::Variable);
- let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref));
+ let ctx = TyLoweringContext::new(
+ db,
+ &resolver,
+ struct_data.variant_data.types_map(),
+ AdtId::from(def).into(),
+ )
+ .with_type_param_mode(ParamLoweringMode::Variable);
+ let params = fields.iter().map(|(_, field)| ctx.lower_ty(field.type_ref));
let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
Binders::new(
binders,
@@ -1961,9 +2038,14 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
let var_data = db.enum_variant_data(def);
let fields = var_data.variant_data.fields();
let resolver = def.resolver(db.upcast());
- let ctx = TyLoweringContext::new(db, &resolver, DefWithBodyId::VariantId(def).into())
- .with_type_param_mode(ParamLoweringMode::Variable);
- let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref));
+ let ctx = TyLoweringContext::new(
+ db,
+ &resolver,
+ var_data.variant_data.types_map(),
+ DefWithBodyId::VariantId(def).into(),
+ )
+ .with_type_param_mode(ParamLoweringMode::Variable);
+ let params = fields.iter().map(|(_, field)| ctx.lower_ty(field.type_ref));
let (ret, binders) =
type_for_adt(db, def.lookup(db.upcast()).parent.into()).into_value_and_skipped_binders();
Binders::new(
@@ -2004,15 +2086,17 @@ fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
let generics = generics(db.upcast(), t.into());
let resolver = t.resolver(db.upcast());
- let ctx = TyLoweringContext::new(db, &resolver, t.into())
+ let type_alias_data = db.type_alias_data(t);
+ let ctx = TyLoweringContext::new(db, &resolver, &type_alias_data.types_map, t.into())
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
.with_type_param_mode(ParamLoweringMode::Variable);
- let type_alias_data = db.type_alias_data(t);
let inner = if type_alias_data.is_extern {
TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner)
} else {
- let type_ref = &type_alias_data.type_ref;
- ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error))
+ type_alias_data
+ .type_ref
+ .map(|type_ref| ctx.lower_ty(type_ref))
+ .unwrap_or_else(|| TyKind::Error.intern(Interner))
};
make_binders(db, &generics, inner)
}
@@ -2085,9 +2169,9 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde
let impl_data = db.impl_data(impl_id);
let resolver = impl_id.resolver(db.upcast());
let generics = generics(db.upcast(), impl_id.into());
- let ctx = TyLoweringContext::new(db, &resolver, impl_id.into())
+ let ctx = TyLoweringContext::new(db, &resolver, &impl_data.types_map, impl_id.into())
.with_type_param_mode(ParamLoweringMode::Variable);
- make_binders(db, &generics, ctx.lower_ty(&impl_data.self_ty))
+ make_binders(db, &generics, ctx.lower_ty(impl_data.self_ty))
}
// returns None if def is a type arg
@@ -2095,13 +2179,13 @@ pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> T
let parent_data = db.generic_params(def.parent());
let data = &parent_data[def.local_id()];
let resolver = def.parent().resolver(db.upcast());
- let ctx = TyLoweringContext::new(db, &resolver, def.parent().into());
+ let ctx = TyLoweringContext::new(db, &resolver, &parent_data.types_map, def.parent().into());
match data {
TypeOrConstParamData::TypeParamData(_) => {
never!();
Ty::new(Interner, TyKind::Error)
}
- TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(&d.ty),
+ TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(d.ty),
}
}
@@ -2117,7 +2201,7 @@ pub(crate) fn impl_self_ty_recover(
pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
let impl_data = db.impl_data(impl_id);
let resolver = impl_id.resolver(db.upcast());
- let ctx = TyLoweringContext::new(db, &resolver, impl_id.into())
+ let ctx = TyLoweringContext::new(db, &resolver, &impl_data.types_map, impl_id.into())
.with_type_param_mode(ParamLoweringMode::Variable);
let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
let target_trait = impl_data.target_trait.as_ref()?;
@@ -2131,10 +2215,10 @@ pub(crate) fn return_type_impl_traits(
// FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
let data = db.function_data(def);
let resolver = def.resolver(db.upcast());
- let ctx_ret = TyLoweringContext::new(db, &resolver, def.into())
+ let ctx_ret = TyLoweringContext::new(db, &resolver, &data.types_map, def.into())
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
.with_type_param_mode(ParamLoweringMode::Variable);
- let _ret = ctx_ret.lower_ty(&data.ret_type);
+ let _ret = ctx_ret.lower_ty(data.ret_type);
let generics = generics(db.upcast(), def.into());
let return_type_impl_traits = ImplTraits {
impl_traits: match ctx_ret.impl_trait_mode {
@@ -2155,10 +2239,10 @@ pub(crate) fn type_alias_impl_traits(
) -> Option<Arc<Binders<ImplTraits>>> {
let data = db.type_alias_data(def);
let resolver = def.resolver(db.upcast());
- let ctx = TyLoweringContext::new(db, &resolver, def.into())
+ let ctx = TyLoweringContext::new(db, &resolver, &data.types_map, def.into())
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
.with_type_param_mode(ParamLoweringMode::Variable);
- if let Some(type_ref) = &data.type_ref {
+ if let Some(type_ref) = data.type_ref {
let _ty = ctx.lower_ty(type_ref);
}
let type_alias_impl_traits = ImplTraits {
@@ -2190,7 +2274,8 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
kind_id: GenericParamId,
arg: &'a GenericArg,
this: &mut T,
- for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
+ types_map: &TypesMap,
+ for_type: impl FnOnce(&mut T, TypeRefId) -> Ty + 'a,
for_const: impl FnOnce(&mut T, &ConstRef, Ty) -> Const + 'a,
for_lifetime: impl FnOnce(&mut T, &LifetimeRef) -> Lifetime + 'a,
) -> crate::GenericArg {
@@ -2203,7 +2288,7 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
GenericParamId::LifetimeParamId(_) => ParamKind::Lifetime,
};
match (arg, kind) {
- (GenericArg::Type(type_ref), ParamKind::Type) => for_type(this, type_ref).cast(Interner),
+ (GenericArg::Type(type_ref), ParamKind::Type) => for_type(this, *type_ref).cast(Interner),
(GenericArg::Const(c), ParamKind::Const(c_ty)) => for_const(this, c, c_ty).cast(Interner),
(GenericArg::Lifetime(lifetime_ref), ParamKind::Lifetime) => {
for_lifetime(this, lifetime_ref).cast(Interner)
@@ -2214,7 +2299,7 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
// We want to recover simple idents, which parser detects them
// as types. Maybe here is not the best place to do it, but
// it works.
- if let TypeRef::Path(p) = t {
+ if let TypeRef::Path(p) = &types_map[*t] {
if let Some(p) = p.mod_path() {
if p.kind == PathKind::Plain {
if let [n] = p.segments() {