Skip to content

Commit 7fa00aa

Browse files
authored
Rollup merge of #143258 - compiler-errors:disambiguator-state, r=oli-obk
Don't recompute `DisambiguatorState` for every RPITIT in trait definition The `associated_type_for_impl_trait_in_trait` currently needs to rerun the `RPITVisitor` for every RPITIT to compute its disambiguator. Instead of synthesizing all of the RPITITs def ids one at a time in different queries, just synthesize them inside of the `associated_types_for_impl_traits_in_associated_fn` query. There we can just share the same `DisambiguatorState` for all the RPITITs in one function signature. r? ``````@Zoxc`````` or ``````@oli-obk`````` cc #140453
2 parents df7cac9 + 08278eb commit 7fa00aa

File tree

3 files changed

+47
-46
lines changed
  • compiler

3 files changed

+47
-46
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2459,13 +2459,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24592459
// type a projection.
24602460
let in_trait = match opaque_ty.origin {
24612461
hir::OpaqueTyOrigin::FnReturn {
2462+
parent,
24622463
in_trait_or_impl: Some(hir::RpitContext::Trait),
24632464
..
24642465
}
24652466
| hir::OpaqueTyOrigin::AsyncFn {
2467+
parent,
24662468
in_trait_or_impl: Some(hir::RpitContext::Trait),
24672469
..
2468-
} => true,
2470+
} => Some(parent),
24692471
hir::OpaqueTyOrigin::FnReturn {
24702472
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
24712473
..
@@ -2474,7 +2476,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24742476
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
24752477
..
24762478
}
2477-
| hir::OpaqueTyOrigin::TyAlias { .. } => false,
2479+
| hir::OpaqueTyOrigin::TyAlias { .. } => None,
24782480
};
24792481

24802482
self.lower_opaque_ty(opaque_ty.def_id, in_trait)
@@ -2594,17 +2596,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
25942596

25952597
/// Lower an opaque type (i.e., an existential impl-Trait type) from the HIR.
25962598
#[instrument(level = "debug", skip(self), ret)]
2597-
fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: bool) -> Ty<'tcx> {
2599+
fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: Option<LocalDefId>) -> Ty<'tcx> {
25982600
let tcx = self.tcx();
25992601

26002602
let lifetimes = tcx.opaque_captured_lifetimes(def_id);
26012603
debug!(?lifetimes);
26022604

2603-
// If this is an RPITIT and we are using the new RPITIT lowering scheme, we
2604-
// generate the def_id of an associated type for the trait and return as
2605-
// type a projection.
2606-
let def_id = if in_trait {
2607-
tcx.associated_type_for_impl_trait_in_trait(def_id).to_def_id()
2605+
// If this is an RPITIT and we are using the new RPITIT lowering scheme,
2606+
// do a linear search to map this to the synthetic associated type that
2607+
// it will be lowered to.
2608+
let def_id = if let Some(parent_def_id) = in_trait {
2609+
*tcx.associated_types_for_impl_traits_in_associated_fn(parent_def_id)
2610+
.iter()
2611+
.find(|rpitit| match tcx.opt_rpitit_info(**rpitit) {
2612+
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
2613+
opaque_def_id.expect_local() == def_id
2614+
}
2615+
_ => unreachable!(),
2616+
})
2617+
.unwrap()
26082618
} else {
26092619
def_id.to_def_id()
26102620
};
@@ -2627,7 +2637,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
26272637
});
26282638
debug!(?args);
26292639

2630-
if in_trait {
2640+
if in_trait.is_some() {
26312641
Ty::new_projection_from_args(tcx, def_id, args)
26322642
} else {
26332643
Ty::new_opaque(tcx, def_id, args)

compiler/rustc_middle/src/query/mod.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,13 +1093,6 @@ rustc_queries! {
10931093
separate_provide_extern
10941094
}
10951095

1096-
/// Given an impl trait in trait `opaque_ty_def_id`, create and return the corresponding
1097-
/// associated item.
1098-
query associated_type_for_impl_trait_in_trait(opaque_ty_def_id: LocalDefId) -> LocalDefId {
1099-
desc { |tcx| "creating the associated item corresponding to the opaque type `{}`", tcx.def_path_str(opaque_ty_def_id.to_def_id()) }
1100-
cache_on_disk_if { true }
1101-
}
1102-
11031096
/// Given an `impl_id`, return the trait it implements along with some header information.
11041097
/// Return `None` if this is an inherent impl.
11051098
query impl_trait_header(impl_id: DefId) -> Option<ty::ImplTraitHeader<'tcx>> {

compiler/rustc_ty_utils/src/assoc.rs

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
use rustc_data_structures::fx::FxIndexSet;
1+
use rustc_hir as hir;
22
use rustc_hir::def::DefKind;
33
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
44
use rustc_hir::definitions::{DefPathData, DisambiguatorState};
55
use rustc_hir::intravisit::{self, Visitor};
6-
use rustc_hir::{self as hir, AmbigArg};
76
use rustc_middle::query::Providers;
87
use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
98
use rustc_middle::{bug, span_bug};
@@ -14,7 +13,6 @@ pub(crate) fn provide(providers: &mut Providers) {
1413
associated_item_def_ids,
1514
associated_items,
1615
associated_types_for_impl_traits_in_associated_fn,
17-
associated_type_for_impl_trait_in_trait,
1816
impl_item_implementor_ids,
1917
..*providers
2018
};
@@ -160,20 +158,22 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A
160158
container: ty::AssocItemContainer::Impl,
161159
}
162160
}
163-
struct RPITVisitor {
164-
rpits: FxIndexSet<LocalDefId>,
161+
struct RPITVisitor<'tcx> {
162+
tcx: TyCtxt<'tcx>,
163+
synthetics: Vec<LocalDefId>,
164+
data: DefPathData,
165+
disambiguator: DisambiguatorState,
165166
}
166167

167-
impl<'tcx> Visitor<'tcx> for RPITVisitor {
168-
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
169-
if let hir::TyKind::OpaqueDef(opaq) = ty.kind
170-
&& self.rpits.insert(opaq.def_id)
171-
{
172-
for bound in opaq.bounds {
173-
intravisit::walk_param_bound(self, bound);
174-
}
175-
}
176-
intravisit::walk_ty(self, ty)
168+
impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
169+
fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) -> Self::Result {
170+
self.synthetics.push(associated_type_for_impl_trait_in_trait(
171+
self.tcx,
172+
opaque.def_id,
173+
self.data,
174+
&mut self.disambiguator,
175+
));
176+
intravisit::walk_opaque_ty(self, opaque)
177177
}
178178
}
179179

@@ -194,14 +194,18 @@ fn associated_types_for_impl_traits_in_associated_fn(
194194

195195
match tcx.def_kind(parent_def_id) {
196196
DefKind::Trait => {
197-
let mut visitor = RPITVisitor { rpits: FxIndexSet::default() };
198-
199197
if let Some(output) = tcx.hir_get_fn_output(fn_def_id) {
198+
let data = DefPathData::AnonAssocTy(tcx.item_name(fn_def_id.to_def_id()));
199+
let mut visitor = RPITVisitor {
200+
tcx,
201+
synthetics: vec![],
202+
data,
203+
disambiguator: DisambiguatorState::with(parent_def_id, data, 0),
204+
};
200205
visitor.visit_fn_ret_ty(output);
201-
202-
tcx.arena.alloc_from_iter(visitor.rpits.iter().map(|opaque_ty_def_id| {
203-
tcx.associated_type_for_impl_trait_in_trait(opaque_ty_def_id).to_def_id()
204-
}))
206+
tcx.arena.alloc_from_iter(
207+
visitor.synthetics.into_iter().map(|def_id| def_id.to_def_id()),
208+
)
205209
} else {
206210
&[]
207211
}
@@ -211,7 +215,6 @@ fn associated_types_for_impl_traits_in_associated_fn(
211215
let Some(trait_fn_def_id) = tcx.associated_item(fn_def_id).trait_item_def_id else {
212216
return &[];
213217
};
214-
215218
tcx.arena.alloc_from_iter(
216219
tcx.associated_types_for_impl_traits_in_associated_fn(trait_fn_def_id).iter().map(
217220
move |&trait_assoc_def_id| {
@@ -236,6 +239,8 @@ fn associated_types_for_impl_traits_in_associated_fn(
236239
fn associated_type_for_impl_trait_in_trait(
237240
tcx: TyCtxt<'_>,
238241
opaque_ty_def_id: LocalDefId,
242+
data: DefPathData,
243+
disambiguator: &mut DisambiguatorState,
239244
) -> LocalDefId {
240245
let (hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. }
241246
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. }) =
@@ -246,22 +251,15 @@ fn associated_type_for_impl_trait_in_trait(
246251
let trait_def_id = tcx.local_parent(fn_def_id);
247252
assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait);
248253

249-
// Collect all opaque types in return position for the method and use
250-
// the index as the disambiguator to make an unique def path.
251-
let mut visitor = RPITVisitor { rpits: FxIndexSet::default() };
252-
visitor.visit_fn_ret_ty(tcx.hir_get_fn_output(fn_def_id).unwrap());
253-
let disambiguator = visitor.rpits.get_index_of(&opaque_ty_def_id).unwrap().try_into().unwrap();
254-
255254
let span = tcx.def_span(opaque_ty_def_id);
256255
// Also use the method name to create an unique def path.
257-
let data = DefPathData::AnonAssocTy(tcx.item_name(fn_def_id.to_def_id()));
258256
let trait_assoc_ty = tcx.at(span).create_def(
259257
trait_def_id,
260258
// No name because this is an anonymous associated type.
261259
None,
262260
DefKind::AssocTy,
263261
Some(data),
264-
&mut DisambiguatorState::with(trait_def_id, data, disambiguator),
262+
disambiguator,
265263
);
266264

267265
let local_def_id = trait_assoc_ty.def_id();

0 commit comments

Comments
 (0)