mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 21:25:25 +00:00 
			
		
		
		
	Build source map for hir_def::TypeRefs
				
					
				
			So that given a `TypeRef` we will be able to trace it back to source code. This is necessary to be able to provide diagnostics for lowering to chalk tys, since the input to that is `TypeRef`. This means that `TypeRef`s now have an identity, which means storing them in arena and not interning them, which is an unfortunate (but necessary) loss but also a pretty massive change. Luckily, because of the separation layer we have for IDE and HIR, this change never crosses the IDE boundary.
This commit is contained in:
		
							parent
							
								
									6a67a4d3cd
								
							
						
					
					
						commit
						89c0ffa6b0
					
				
					 40 changed files with 1712 additions and 778 deletions
				
			
		| 
						 | 
				
			
			@ -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,21 +293,21 @@ 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 inner_ty = self.lower_ty(*inner);
 | 
			
		||||
                let const_len = self.lower_const(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);
 | 
			
		||||
                let inner_ty = self.lower_ty(*inner);
 | 
			
		||||
                // 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));
 | 
			
		||||
| 
						 | 
				
			
			@ -290,9 +315,12 @@ impl<'a> TyLoweringContext<'a> {
 | 
			
		|||
                    .intern(Interner)
 | 
			
		||||
            }
 | 
			
		||||
            TypeRef::Placeholder => TyKind::Error.intern(Interner),
 | 
			
		||||
            &TypeRef::Fn(ref params, variadic, is_unsafe, ref abi) => {
 | 
			
		||||
            &TypeRef::Fn { ref params, is_varargs: variadic, is_unsafe, ref abi } => {
 | 
			
		||||
                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,
 | 
			
		||||
                        params.iter().map(|&(_, tr)| ctx.lower_ty(tr)),
 | 
			
		||||
                    )
 | 
			
		||||
                });
 | 
			
		||||
                TyKind::Function(FnPointer {
 | 
			
		||||
                    num_binders: 0, // FIXME lower `for<'a> fn()` correctly
 | 
			
		||||
| 
						 | 
				
			
			@ -351,8 +379,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 +404,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 +460,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 +519,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 +720,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 +921,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 +958,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 +1056,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 +1087,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)
 | 
			
		||||
| 
						 | 
				
			
			@ -1079,10 +1137,10 @@ 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()
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -1111,7 +1169,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)),
 | 
			
		||||
| 
						 | 
				
			
			@ -1131,8 +1189,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) => (),
 | 
			
		||||
                        (
 | 
			
		||||
                            _,
 | 
			
		||||
| 
						 | 
				
			
			@ -1179,6 +1237,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);
 | 
			
		||||
| 
						 | 
				
			
			@ -1216,7 +1276,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
 | 
			
		||||
| 
						 | 
				
			
			@ -1314,7 +1374,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| {
 | 
			
		||||
| 
						 | 
				
			
			@ -1366,6 +1426,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).
 | 
			
		||||
| 
						 | 
				
			
			@ -1386,17 +1457,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
 | 
			
		||||
| 
						 | 
				
			
			@ -1500,10 +1560,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)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1523,38 +1583,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.
 | 
			
		||||
| 
						 | 
				
			
			@ -1577,13 +1637,15 @@ pub(crate) fn generic_predicates_for_param_query(
 | 
			
		|||
        }
 | 
			
		||||
        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 = ¶ms.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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1630,23 +1692,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 = ¶ms.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));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1725,18 +1791,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 = ¶ms.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);
 | 
			
		||||
| 
						 | 
				
			
			@ -1812,18 +1880,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))
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -1835,7 +1904,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)
 | 
			
		||||
                        },
 | 
			
		||||
                    );
 | 
			
		||||
| 
						 | 
				
			
			@ -1875,14 +1944,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,
 | 
			
		||||
| 
						 | 
				
			
			@ -1911,28 +1980,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,
 | 
			
		||||
| 
						 | 
				
			
			@ -1962,9 +2036,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(
 | 
			
		||||
| 
						 | 
				
			
			@ -2005,15 +2084,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)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2086,9 +2167,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
 | 
			
		||||
| 
						 | 
				
			
			@ -2096,13 +2177,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),
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2118,7 +2199,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()?;
 | 
			
		||||
| 
						 | 
				
			
			@ -2132,10 +2213,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 {
 | 
			
		||||
| 
						 | 
				
			
			@ -2156,10 +2237,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 {
 | 
			
		||||
| 
						 | 
				
			
			@ -2191,7 +2272,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 {
 | 
			
		||||
| 
						 | 
				
			
			@ -2204,7 +2286,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)
 | 
			
		||||
| 
						 | 
				
			
			@ -2215,7 +2297,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() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue