diff options
| author | bors <bors@rust-lang.org> | 2018-11-12 08:03:58 +0000 | 
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-11-12 08:03:58 +0000 | 
| commit | 0195812aeafeecaa8760a4ddceae187472db8fe6 (patch) | |
| tree | e86085acecc17de6521f375dec1741413b3cb371 /src | |
| parent | d1d79ae3ad36e82e2be33bea108d6a4e98ddce0b (diff) | |
| parent | e927a244ea8f162858594552ddaec8465d54c329 (diff) | |
| download | rust-0195812aeafeecaa8760a4ddceae187472db8fe6.tar.gz rust-0195812aeafeecaa8760a4ddceae187472db8fe6.zip | |
Auto merge of #55604 - nnethercote:avoid-associated_items-Box, r=nnethercote
Avoid the Box in `TyCtxt::associated_items`. This reduces instruction counts on `packed_simd` by 2%. r? @nikomatsakis
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/traits/specialize/specialization_graph.rs | 2 | ||||
| -rw-r--r-- | src/librustc/ty/mod.rs | 31 | 
2 files changed, 28 insertions, 5 deletions
| diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index e237cab5ea1..e44e1453b79 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -366,7 +366,7 @@ impl<'a, 'gcx, 'tcx> Node { pub fn items( &self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - ) -> impl Iterator<Item = ty::AssociatedItem> + 'a { + ) -> ty::AssociatedItemsIterator<'a, 'gcx, 'tcx> { tcx.associated_items(self.def_id()) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index ef9b3e3efab..9a63bb374c6 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2674,10 +2674,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn associated_items( self, def_id: DefId, - ) -> impl Iterator<Item = AssociatedItem> + 'a { - let def_ids = self.associated_item_def_ids(def_id); - Box::new((0..def_ids.len()).map(move |i| self.associated_item(def_ids[i]))) - as Box<dyn Iterator<Item = AssociatedItem> + 'a> + ) -> AssociatedItemsIterator<'a, 'gcx, '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 + AssociatedItemsIterator { + 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 @@ -2874,6 +2881,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } +pub struct AssociatedItemsIterator<'a, 'gcx: 'tcx, 'tcx: 'a> { + tcx: TyCtxt<'a, 'gcx, 'tcx>, + def_ids: Lrc<Vec<DefId>>, + next_index: usize, +} + +impl Iterator for AssociatedItemsIterator<'_, '_, '_> { + type Item = AssociatedItem; + + fn next(&mut self) -> Option<AssociatedItem> { + let def_id = self.def_ids.get(self.next_index)?; + self.next_index += 1; + Some(self.tcx.associated_item(*def_id)) + } +} + impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn with_freevars<T, F>(self, fid: NodeId, f: F) -> T where F: FnOnce(&[hir::Freevar]) -> T, | 
