From 4fc4b951f1da755298aea69f10a4951745ee8501 Mon Sep 17 00:00:00 2001 From: Jonas Schievink <jonasschievink@gmail.com> Date: Wed, 5 Feb 2020 01:43:03 +0100 Subject: [PATCH] Make associated item lookup a query --- src/librustc/query/mod.rs | 5 +++++ src/librustc/ty/mod.rs | 31 ++++++++++--------------------- src/librustc_ty/ty.rs | 9 +++++++++ 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 37d5e23535b81..228271e0c4c3a 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -310,6 +310,11 @@ rustc_queries! { /// Maps from a trait item to the trait item "descriptor". query associated_item(_: DefId) -> ty::AssocItem {} + /// Collects the associated items defined on a trait or impl. + query associated_items(key: DefId) -> ty::AssocItemsIterator<'tcx> { + desc { |tcx| "collecting associated items of {}", tcx.def_path_str(key) } + } + query impl_trait_ref(_: DefId) -> Option<ty::TraitRef<'tcx>> {} query impl_polarity(_: DefId) -> ty::ImplPolarity {} diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f417b907a3811..028a88a6c82b3 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2741,19 +2741,6 @@ impl<'tcx> TyCtxt<'tcx> { variant.fields.iter().position(|field| self.hygienic_eq(ident, field.ident, variant.def_id)) } - pub fn associated_items(self, def_id: DefId) -> AssocItemsIterator<'tcx> { - // Ideally, we would use `-> impl Iterator` here, but it falls - // afoul of the conservative "capture [restrictions]" we put - // in place, so we use a hand-written iterator. - // - // [restrictions]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999 - AssocItemsIterator { - tcx: self, - def_ids: self.associated_item_def_ids(def_id), - next_index: 0, - } - } - /// Returns `true` if the impls are the same polarity and the trait either /// has no items or is annotated #[marker] and prevents item overrides. pub fn impls_are_allowed_to_overlap( @@ -2993,20 +2980,22 @@ impl<'tcx> TyCtxt<'tcx> { } } -#[derive(Clone)] +#[derive(Copy, Clone, HashStable)] pub struct AssocItemsIterator<'tcx> { - tcx: TyCtxt<'tcx>, - def_ids: &'tcx [DefId], - next_index: usize, + pub items: &'tcx [AssocItem], } -impl Iterator for AssocItemsIterator<'_> { +impl<'tcx> Iterator for AssocItemsIterator<'tcx> { type Item = AssocItem; + #[inline] fn next(&mut self) -> Option<AssocItem> { - let def_id = self.def_ids.get(self.next_index)?; - self.next_index += 1; - Some(self.tcx.associated_item(*def_id)) + if let Some((first, rest)) = self.items.split_first() { + self.items = rest; + Some(*first) + } else { + None + } } } diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index 8f882be1a090e..e2a9b821b4a0a 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -206,6 +206,14 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { } } +fn associated_items<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AssocItemsIterator<'tcx> { + ty::AssocItemsIterator { + items: tcx.arena.alloc_from_iter( + tcx.associated_item_def_ids(def_id).iter().map(|did| tcx.associated_item(*did)), + ), + } +} + fn def_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span { tcx.hir().span_if_local(def_id).unwrap() } @@ -356,6 +364,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { asyncness, associated_item, associated_item_def_ids, + associated_items, adt_sized_constraint, def_span, param_env,