about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs4
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs6
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs36
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs3
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs5
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs190
9 files changed, 110 insertions, 146 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 379ce69bdea..87db80f2423 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -15,7 +15,6 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::{
     self, BottomUpFolder, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeFolder,
     TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
-    associated_types_for_impl_traits_in_associated_fn,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_span::{DUMMY_SP, Span};
@@ -758,7 +757,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     // returning `-> Missing<impl Sized>`, that gets converted to `-> {type error}`,
     // and when walking through the signature we end up never collecting the def id
     // of the `impl Sized`. Insert that here, so we don't ICE later.
-    for assoc_item in associated_types_for_impl_traits_in_associated_fn(tcx, trait_m.def_id) {
+    for assoc_item in tcx.associated_types_for_impl_traits_in_associated_fn(trait_m.def_id) {
         if !remapped_types.contains_key(assoc_item) {
             remapped_types.insert(
                 *assoc_item,
@@ -2449,7 +2448,8 @@ fn param_env_with_gat_bounds<'tcx>(
                     ty::ImplTraitInTraitData::Impl { fn_def_id }
                     | ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
                 ),
-        } => associated_types_for_impl_traits_in_associated_fn(tcx, fn_def_id)
+        } => tcx
+            .associated_types_for_impl_traits_in_associated_fn(fn_def_id)
             .iter()
             .map(|def_id| tcx.associated_item(*def_id))
             .collect(),
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 3d3fdd899d3..607028f4d9a 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -20,7 +20,7 @@ use rustc_middle::ty::trait_def::TraitSpecializationKind;
 use rustc_middle::ty::{
     self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFlags,
     TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
-    Upcast, associated_types_for_impl_traits_in_associated_fn,
+    Upcast,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_session::parse::feature_err;
@@ -327,7 +327,7 @@ pub(crate) fn check_trait_item<'tcx>(
 
     if matches!(tcx.def_kind(def_id), DefKind::AssocFn) {
         for &assoc_ty_def_id in
-            associated_types_for_impl_traits_in_associated_fn(tcx, def_id.to_def_id())
+            tcx.associated_types_for_impl_traits_in_associated_fn(def_id.to_def_id())
         {
             res = res.and(check_associated_item(tcx, assoc_ty_def_id.expect_local()));
         }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index ae56f0c5160..a5bd7c1a34a 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -40,7 +40,7 @@ use rustc_middle::mir::interpret::LitToConstInput;
 use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
 use rustc_middle::ty::{
     self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt,
-    TypingMode, Upcast, associated_types_for_impl_traits_in_associated_fn, fold_regions,
+    TypingMode, Upcast, fold_regions,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
@@ -2602,7 +2602,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // do a linear search to map this to the synthetic associated type that
         // it will be lowered to.
         let def_id = if let Some(parent_def_id) = in_trait {
-            *associated_types_for_impl_traits_in_associated_fn(tcx, parent_def_id.to_def_id())
+            *tcx.associated_types_for_impl_traits_in_associated_fn(parent_def_id.to_def_id())
                 .iter()
                 .find(|rpitit| match tcx.opt_rpitit_info(**rpitit) {
                     Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 213090d7d47..8347626080e 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -481,7 +481,7 @@ define_tables! {
     assumed_wf_types_for_rpitit: Table<DefIndex, LazyArray<(Ty<'static>, Span)>>,
     opaque_ty_origin: Table<DefIndex, LazyValue<hir::OpaqueTyOrigin<DefId>>>,
     anon_const_kind: Table<DefIndex, LazyValue<ty::AnonConstKind>>,
-    associated_types_for_impl_traits_in_trait_or_impl: Table<DefIndex, LazyValue<ty::AssocTyForImplTraitInTraitOrImpl>>,
+    associated_types_for_impl_traits_in_trait_or_impl: Table<DefIndex, LazyValue<DefIdMap<Vec<DefId>>>>,
 }
 
 #[derive(TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 3da6c6f5fe1..842d118449a 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1079,9 +1079,11 @@ rustc_queries! {
         desc { |tcx| "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) }
     }
 
-    query associated_types_for_impl_traits_in_trait_or_impl(did: DefId) -> &'tcx ty::AssocTyForImplTraitInTraitOrImpl {
+    /// Given the `item_def_id` of a trait or impl, return a mapping from associated fn def id
+    /// to its associated type items that correspond to the RPITITs in its signature.
+    query associated_types_for_impl_traits_in_trait_or_impl(item_def_id: DefId) -> &'tcx DefIdMap<Vec<DefId>> {
         arena_cache
-        desc { |tcx| "creating rpitit for `{}`", tcx.def_path_str(did) }
+        desc { |tcx| "synthesizing RPITIT items for the opaque types for methods in `{}`", tcx.def_path_str(item_def_id) }
         separate_provide_extern
     }
 
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index 99714171c72..9534d45e495 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -1,5 +1,4 @@
 use rustc_attr_data_structures::{AttributeKind, find_attr};
-use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sorted_map::SortedIndexMultiMap;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Namespace};
@@ -287,22 +286,21 @@ impl AssocItems {
     }
 }
 
-#[derive(Debug, Clone, PartialEq, Encodable, Decodable, HashStable)]
-pub struct AssocTyForImplTraitInTraitOrImpl(pub FxIndexMap<DefId, Vec<DefId>>);
-
-/// Given an `fn_def_id` of a trait or a trait implementation:
-///
-/// if `fn_def_id` is a function defined inside a trait, then it synthesizes
-/// a new def id corresponding to a new associated type for each return-
-/// position `impl Trait` in the signature.
-///
-/// if `fn_def_id` is a function inside of an impl, then for each synthetic
-/// associated type generated for the corresponding trait function described
-/// above, synthesize a corresponding associated type in the impl.
-pub fn associated_types_for_impl_traits_in_associated_fn(
-    tcx: TyCtxt<'_>,
-    fn_def_id: DefId,
-) -> &'_ [DefId] {
-    let parent_def_id = tcx.parent(fn_def_id);
-    &tcx.associated_types_for_impl_traits_in_trait_or_impl(parent_def_id).0[&fn_def_id]
+impl<'tcx> TyCtxt<'tcx> {
+    /// Given an `fn_def_id` of a trait or a trait implementation:
+    ///
+    /// if `fn_def_id` is a function defined inside a trait, then it synthesizes
+    /// a new def id corresponding to a new associated type for each return-
+    /// position `impl Trait` in the signature.
+    ///
+    /// if `fn_def_id` is a function inside of an impl, then for each synthetic
+    /// associated type generated for the corresponding trait function described
+    /// above, synthesize a corresponding associated type in the impl.
+    pub fn associated_types_for_impl_traits_in_associated_fn(
+        self,
+        fn_def_id: DefId,
+    ) -> &'tcx [DefId] {
+        let parent_def_id = self.parent(fn_def_id);
+        &self.associated_types_for_impl_traits_in_trait_or_impl(parent_def_id)[&fn_def_id]
+    }
 }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index e1b11e4f54a..0177a95498b 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -2194,7 +2194,8 @@ impl<'tcx> TyCtxt<'tcx> {
             return false;
         };
 
-        return !associated_types_for_impl_traits_in_associated_fn(self, trait_item_def_id)
+        return !self
+            .associated_types_for_impl_traits_in_associated_fn(trait_item_def_id)
             .is_empty();
     }
 }
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index 88f6e717af4..3d601fc0533 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -23,6 +23,10 @@ impl<A: ParameterizedOverTcx, B: ParameterizedOverTcx> ParameterizedOverTcx for
     type Value<'tcx> = (A::Value<'tcx>, B::Value<'tcx>);
 }
 
+impl<T: ParameterizedOverTcx> ParameterizedOverTcx for Vec<T> {
+    type Value<'tcx> = Vec<T::Value<'tcx>>;
+}
+
 impl<I: Idx + 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for IndexVec<I, T> {
     type Value<'tcx> = IndexVec<I, T::Value<'tcx>>;
 }
@@ -67,7 +71,6 @@ trivially_parameterized_over_tcx! {
     crate::mir::ConstQualifs,
     ty::AsyncDestructor,
     ty::AssocItemContainer,
-    ty::AssocTyForImplTraitInTraitOrImpl,
     ty::Asyncness,
     ty::AnonConstKind,
     ty::DeducedParamAttrs,
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 400158496b5..66c44f72f4e 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -1,15 +1,11 @@
-use std::collections::hash_map::Entry;
-
-use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_hir::definitions::{DefPathData, DisambiguatorState};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{self as hir, ItemKind};
 use rustc_middle::query::Providers;
-use rustc_middle::ty::{self, AssocTyForImplTraitInTraitOrImpl, ImplTraitInTraitData, TyCtxt};
+use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
 use rustc_middle::{bug, span_bug};
-use rustc_span::Symbol;
 
 pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers {
@@ -26,39 +22,28 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] {
     let item = tcx.hir_expect_item(def_id);
     match item.kind {
         hir::ItemKind::Trait(.., trait_item_refs) => {
-            // We collect RPITITs for each trait method's return type and create a
-            // corresponding associated item using associated_types_for_impl_traits_in_trait_or_impl
+            // We collect RPITITs for each trait method's return type and create a corresponding
+            // associated item using the associated_types_for_impl_traits_in_trait_or_impl
             // query.
-            tcx.arena.alloc_from_iter(
-                trait_item_refs
-                    .iter()
-                    .map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id())
-                    .chain(
-                        tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id)
-                            .0
-                            .values()
-                            .flatten()
-                            .copied(),
-                    ),
-            )
+            let rpitit_items = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id);
+            tcx.arena.alloc_from_iter(trait_item_refs.iter().flat_map(|trait_item_ref| {
+                let item_def_id = trait_item_ref.id.owner_id.to_def_id();
+                [item_def_id]
+                    .into_iter()
+                    .chain(rpitit_items.get(&item_def_id).into_iter().flatten().copied())
+            }))
         }
         hir::ItemKind::Impl(impl_) => {
             // We collect RPITITs for each trait method's return type, on the impl side too and
             // create a corresponding associated item using
             // associated_types_for_impl_traits_in_trait_or_impl query.
-            tcx.arena.alloc_from_iter(
-                impl_
-                    .items
-                    .iter()
-                    .map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id())
-                    .chain(impl_.of_trait.iter().flat_map(|_| {
-                        tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id)
-                            .0
-                            .values()
-                            .flatten()
-                            .copied()
-                    })),
-            )
+            let rpitit_items = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id);
+            tcx.arena.alloc_from_iter(impl_.items.iter().flat_map(|impl_item_ref| {
+                let item_def_id = impl_item_ref.id.owner_id.to_def_id();
+                [item_def_id]
+                    .into_iter()
+                    .chain(rpitit_items.get(&item_def_id).into_iter().flatten().copied())
+            }))
         }
         _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"),
     }
@@ -147,15 +132,15 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A
         container: ty::AssocItemContainer::Impl,
     }
 }
-struct RPITVisitor<'tcx> {
+struct RPITVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     synthetics: Vec<LocalDefId>,
     data: DefPathData,
-    disambiguator: DisambiguatorState,
+    disambiguator: &'a mut DisambiguatorState,
     depth: u32,
 }
 
-impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
+impl<'tcx> Visitor<'tcx> for RPITVisitor<'_, 'tcx> {
     fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) -> Self::Result {
         self.depth += 1;
         self.synthetics.push(associated_type_for_impl_trait_in_trait(
@@ -171,90 +156,64 @@ impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
 fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
-) -> AssocTyForImplTraitInTraitOrImpl {
+) -> DefIdMap<Vec<DefId>> {
     let item = tcx.hir_expect_item(def_id);
+    let disambiguator = &mut DisambiguatorState::new();
     match item.kind {
-        ItemKind::Trait(.., trait_item_refs) => {
-            let mut disambiguator_idx_map = FxHashMap::default();
-            let find_disambiguator_idx =
-                |map: &mut FxHashMap<Symbol, u32>, name| match map.entry(name) {
-                    Entry::Occupied(occ) => *occ.get() + 1,
-                    Entry::Vacant(vac) => {
-                        vac.insert(0);
-                        0
-                    }
+        ItemKind::Trait(.., trait_item_refs) => trait_item_refs
+            .iter()
+            .filter_map(move |item| {
+                if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
+                    return None;
+                }
+                let fn_def_id = item.id.owner_id.def_id;
+                let Some(output) = tcx.hir_get_fn_output(fn_def_id) else {
+                    return Some((fn_def_id.to_def_id(), vec![]));
                 };
-            let update_disambiguator_idx = |map: &mut FxHashMap<Symbol, u32>, name, offset: u32| {
-                *map.get_mut(&name).unwrap() += offset
-            };
-
-            ty::AssocTyForImplTraitInTraitOrImpl(
-                trait_item_refs
-                    .iter()
-                    .filter_map(move |item| {
-                        if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
-                            return None;
-                        }
-                        let fn_def_id = item.id.owner_id.def_id;
-                        let Some(output) = tcx.hir_get_fn_output(fn_def_id) else {
-                            return Some((fn_def_id.to_def_id(), vec![]));
-                        };
-                        let def_name = tcx.item_name(fn_def_id.to_def_id());
-                        let disambiguator_idx =
-                            find_disambiguator_idx(&mut disambiguator_idx_map, def_name);
-                        let data = DefPathData::AnonAssocTy(def_name);
-                        let mut visitor = RPITVisitor {
-                            tcx,
-                            synthetics: vec![],
-                            data,
-                            depth: 0,
-                            disambiguator: DisambiguatorState::with(
-                                def_id,
-                                data,
-                                disambiguator_idx,
-                            ),
-                        };
-                        visitor.visit_fn_ret_ty(output);
-                        update_disambiguator_idx(
-                            &mut disambiguator_idx_map,
-                            def_name,
-                            visitor.depth,
-                        );
-                        let defs = visitor
-                            .synthetics
-                            .into_iter()
-                            .map(|def_id| def_id.to_def_id())
-                            .collect::<Vec<_>>();
-                        Some((fn_def_id.to_def_id(), defs))
-                    })
-                    .collect::<FxIndexMap<_, _>>(),
-            )
-        }
+                let def_name = tcx.item_name(fn_def_id.to_def_id());
+                let data = DefPathData::AnonAssocTy(def_name);
+                let mut visitor =
+                    RPITVisitor { tcx, synthetics: vec![], data, depth: 0, disambiguator };
+                visitor.visit_fn_ret_ty(output);
+                let defs = visitor
+                    .synthetics
+                    .into_iter()
+                    .map(|def_id| def_id.to_def_id())
+                    .collect::<Vec<_>>();
+                Some((fn_def_id.to_def_id(), defs))
+            })
+            .collect(),
         ItemKind::Impl(impl_) => {
-            let Some(trait_did) = tcx.impl_trait_ref(def_id).map(|t| t.skip_binder().def_id) else {
-                return ty::AssocTyForImplTraitInTraitOrImpl(Default::default());
+            let Some(trait_ref) = impl_.of_trait else {
+                return Default::default();
             };
-            let in_trait_def = tcx.associated_types_for_impl_traits_in_trait_or_impl(trait_did);
-            ty::AssocTyForImplTraitInTraitOrImpl(
-                impl_
-                    .items
-                    .iter()
-                    .filter_map(|item| {
-                        if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
-                            return None;
-                        }
-                        let did = item.id.owner_id.def_id.to_def_id();
-                        let Some(trait_item_def_id) = item.trait_item_def_id else {
-                            return Some((did, vec![]));
-                        };
-                        let iter = in_trait_def.0[&trait_item_def_id].iter().map(|&id| {
-                            associated_type_for_impl_trait_in_impl(tcx, id, item.id.owner_id.def_id)
-                                .to_def_id()
-                        });
-                        Some((did, iter.collect()))
-                    })
-                    .collect::<FxIndexMap<_, _>>(),
-            )
+            let Some(trait_def_id) = trait_ref.trait_def_id() else {
+                return Default::default();
+            };
+            let in_trait_def = tcx.associated_types_for_impl_traits_in_trait_or_impl(trait_def_id);
+            impl_
+                .items
+                .iter()
+                .filter_map(|item| {
+                    if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
+                        return None;
+                    }
+                    let did = item.id.owner_id.def_id.to_def_id();
+                    let Some(trait_item_def_id) = item.trait_item_def_id else {
+                        return Some((did, vec![]));
+                    };
+                    let iter = in_trait_def[&trait_item_def_id].iter().map(|&id| {
+                        associated_type_for_impl_trait_in_impl(
+                            tcx,
+                            id,
+                            item.id.owner_id.def_id,
+                            disambiguator,
+                        )
+                        .to_def_id()
+                    });
+                    Some((did, iter.collect()))
+                })
+                .collect()
         }
         _ => {
             bug!(
@@ -336,6 +295,7 @@ fn associated_type_for_impl_trait_in_impl(
     tcx: TyCtxt<'_>,
     trait_assoc_def_id: DefId,
     impl_fn_def_id: LocalDefId,
+    disambiguator: &mut DisambiguatorState,
 ) -> LocalDefId {
     let impl_local_def_id = tcx.local_parent(impl_fn_def_id);
 
@@ -358,7 +318,7 @@ fn associated_type_for_impl_trait_in_impl(
         None,
         DefKind::AssocTy,
         Some(data),
-        &mut DisambiguatorState::with(impl_local_def_id, data, disambiguated_data.disambiguator),
+        disambiguator,
     );
 
     let local_def_id = impl_assoc_ty.def_id();