Skip to content

Commit f6bfdf4

Browse files
authored
Rollup merge of rust-lang#68837 - jonas-schievink:assoc-item-lookup-2, r=estebank
Make associated item collection a query Before this change, every time associated items were iterated over (which rustc does *a lot* – this can probably be further optimized), there would be N+1 queries to fetch all assoc. items. Now there's just one after they've been computed once.
2 parents 424304a + 4fc4b95 commit f6bfdf4

File tree

3 files changed

+24
-21
lines changed

3 files changed

+24
-21
lines changed

src/librustc/query/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,11 @@ rustc_queries! {
310310
/// Maps from a trait item to the trait item "descriptor".
311311
query associated_item(_: DefId) -> ty::AssocItem {}
312312

313+
/// Collects the associated items defined on a trait or impl.
314+
query associated_items(key: DefId) -> ty::AssocItemsIterator<'tcx> {
315+
desc { |tcx| "collecting associated items of {}", tcx.def_path_str(key) }
316+
}
317+
313318
query impl_trait_ref(_: DefId) -> Option<ty::TraitRef<'tcx>> {}
314319
query impl_polarity(_: DefId) -> ty::ImplPolarity {}
315320

src/librustc/ty/mod.rs

+10-21
Original file line numberDiff line numberDiff line change
@@ -2743,19 +2743,6 @@ impl<'tcx> TyCtxt<'tcx> {
27432743
variant.fields.iter().position(|field| self.hygienic_eq(ident, field.ident, variant.def_id))
27442744
}
27452745

2746-
pub fn associated_items(self, def_id: DefId) -> AssocItemsIterator<'tcx> {
2747-
// Ideally, we would use `-> impl Iterator` here, but it falls
2748-
// afoul of the conservative "capture [restrictions]" we put
2749-
// in place, so we use a hand-written iterator.
2750-
//
2751-
// [restrictions]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999
2752-
AssocItemsIterator {
2753-
tcx: self,
2754-
def_ids: self.associated_item_def_ids(def_id),
2755-
next_index: 0,
2756-
}
2757-
}
2758-
27592746
/// Returns `true` if the impls are the same polarity and the trait either
27602747
/// has no items or is annotated #[marker] and prevents item overrides.
27612748
pub fn impls_are_allowed_to_overlap(
@@ -2987,20 +2974,22 @@ impl<'tcx> TyCtxt<'tcx> {
29872974
}
29882975
}
29892976

2990-
#[derive(Clone)]
2977+
#[derive(Copy, Clone, HashStable)]
29912978
pub struct AssocItemsIterator<'tcx> {
2992-
tcx: TyCtxt<'tcx>,
2993-
def_ids: &'tcx [DefId],
2994-
next_index: usize,
2979+
pub items: &'tcx [AssocItem],
29952980
}
29962981

2997-
impl Iterator for AssocItemsIterator<'_> {
2982+
impl<'tcx> Iterator for AssocItemsIterator<'tcx> {
29982983
type Item = AssocItem;
29992984

2985+
#[inline]
30002986
fn next(&mut self) -> Option<AssocItem> {
3001-
let def_id = self.def_ids.get(self.next_index)?;
3002-
self.next_index += 1;
3003-
Some(self.tcx.associated_item(*def_id))
2987+
if let Some((first, rest)) = self.items.split_first() {
2988+
self.items = rest;
2989+
Some(*first)
2990+
} else {
2991+
None
2992+
}
30042993
}
30052994
}
30062995

src/librustc_ty/ty.rs

+9
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,14 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] {
206206
}
207207
}
208208

209+
fn associated_items<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AssocItemsIterator<'tcx> {
210+
ty::AssocItemsIterator {
211+
items: tcx.arena.alloc_from_iter(
212+
tcx.associated_item_def_ids(def_id).iter().map(|did| tcx.associated_item(*did)),
213+
),
214+
}
215+
}
216+
209217
fn def_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span {
210218
tcx.hir().span_if_local(def_id).unwrap()
211219
}
@@ -356,6 +364,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
356364
asyncness,
357365
associated_item,
358366
associated_item_def_ids,
367+
associated_items,
359368
adt_sized_constraint,
360369
def_span,
361370
param_env,

0 commit comments

Comments
 (0)