]> git.lizzy.rs Git - rust.git/blobdiff - src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
Auto merge of #107843 - bjorn3:sync_cg_clif-2023-02-09, r=bjorn3
[rust.git] / src / tools / rust-analyzer / crates / hir-ty / src / lower.rs
index baf9842d5fbf262101c6171f215456f48e31895e..592410008a679c3e979cd3b34d21d3215577e986 100644 (file)
@@ -603,9 +603,8 @@ pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) {
     }
 
     fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
-        let (def, res) = match (self.resolver.generic_def(), res) {
-            (Some(def), Some(res)) => (def, res),
-            _ => return TyKind::Error.intern(Interner),
+        let Some((def, res)) = self.resolver.generic_def().zip(res) else {
+            return TyKind::Error.intern(Interner);
         };
         let ty = named_associated_type_shorthand_candidates(
             self.db,
@@ -617,6 +616,21 @@ fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>)
                     return None;
                 }
 
+                let parent_subst = t.substitution.clone();
+                let parent_subst = match self.type_param_mode {
+                    ParamLoweringMode::Placeholder => {
+                        // if we're lowering to placeholders, we have to put them in now.
+                        let generics = generics(self.db.upcast(), def);
+                        let s = generics.placeholder_subst(self.db);
+                        s.apply(parent_subst, Interner)
+                    }
+                    ParamLoweringMode::Variable => {
+                        // We need to shift in the bound vars, since
+                        // `named_associated_type_shorthand_candidates` does not do that.
+                        parent_subst.shifted_in_from(Interner, self.in_binders)
+                    }
+                };
+
                 // FIXME: `substs_from_path_segment()` pushes `TyKind::Error` for every parent
                 // generic params. It's inefficient to splice the `Substitution`s, so we may want
                 // that method to optionally take parent `Substitution` as we already know them at
@@ -632,22 +646,9 @@ fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>)
 
                 let substs = Substitution::from_iter(
                     Interner,
-                    substs.iter(Interner).take(len_self).chain(t.substitution.iter(Interner)),
+                    substs.iter(Interner).take(len_self).chain(parent_subst.iter(Interner)),
                 );
 
-                let substs = match self.type_param_mode {
-                    ParamLoweringMode::Placeholder => {
-                        // if we're lowering to placeholders, we have to put
-                        // them in now
-                        let generics = generics(self.db.upcast(), def);
-                        let s = generics.placeholder_subst(self.db);
-                        s.apply(substs, Interner)
-                    }
-                    ParamLoweringMode::Variable => substs,
-                };
-                // We need to shift in the bound vars, since
-                // associated_type_shorthand_candidates does not do that
-                let substs = substs.shifted_in_from(Interner, self.in_binders);
                 Some(
                     TyKind::Alias(AliasTy::Projection(ProjectionTy {
                         associated_ty_id: to_assoc_type_id(associated_ty),
@@ -779,7 +780,7 @@ fn substs_from_path_segment(
                         |_, c, ty| {
                             const_or_path_to_chalk(
                                 self.db,
-                                &self.resolver,
+                                self.resolver,
                                 ty,
                                 c,
                                 self.type_param_mode,
@@ -1190,9 +1191,9 @@ pub fn associated_type_shorthand_candidates<R>(
     db: &dyn HirDatabase,
     def: GenericDefId,
     res: TypeNs,
-    cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
+    mut cb: impl FnMut(&Name, TypeAliasId) -> Option<R>,
 ) -> Option<R> {
-    named_associated_type_shorthand_candidates(db, def, res, None, cb)
+    named_associated_type_shorthand_candidates(db, def, res, None, |name, _, id| cb(name, id))
 }
 
 fn named_associated_type_shorthand_candidates<R>(
@@ -1202,6 +1203,9 @@ fn named_associated_type_shorthand_candidates<R>(
     def: GenericDefId,
     res: TypeNs,
     assoc_name: Option<Name>,
+    // Do NOT let `cb` touch `TraitRef` outside of `TyLoweringContext`. Its substitution contains
+    // free `BoundVar`s that need to be shifted and only `TyLoweringContext` knows how to do that
+    // properly (see `TyLoweringContext::select_associated_type()`).
     mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
 ) -> Option<R> {
     let mut search = |t| {
@@ -1792,8 +1796,7 @@ 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 _cx = stdx::panic_context::enter(format!(
-        "impl_self_ty_query({:?} -> {:?} -> {:?})",
-        impl_id, impl_loc, impl_data
+        "impl_self_ty_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})"
     ));
     let generics = generics(db.upcast(), impl_id.into());
     let ctx =
@@ -1830,8 +1833,7 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<
     let impl_data = db.impl_data(impl_id);
     let resolver = impl_id.resolver(db.upcast());
     let _cx = stdx::panic_context::enter(format!(
-        "impl_trait_query({:?} -> {:?} -> {:?})",
-        impl_id, impl_loc, impl_data
+        "impl_trait_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})"
     ));
     let ctx =
         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
@@ -1850,7 +1852,7 @@ pub(crate) fn return_type_impl_traits(
     let ctx_ret = TyLoweringContext::new(db, &resolver)
         .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 =
         ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
@@ -1979,7 +1981,7 @@ fn fallback_bound_vars<T: TypeFoldable<Interner> + HasInterner<Interner = Intern
             if bound.index_if_innermost().map_or(true, is_allowed) {
                 bound.shifted_in_from(binders).to_const(Interner, ty)
             } else {
-                unknown_const(ty.clone())
+                unknown_const(ty)
             }
         },
     )