@@ -2674,10 +2674,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
26742674 pub fn associated_items(
26752675 self,
26762676 def_id: DefId,
2677- ) -> impl Iterator<Item = AssociatedItem> + 'a {
2678- let def_ids = self.associated_item_def_ids(def_id);
2679- Box::new((0..def_ids.len()).map(move |i| self.associated_item(def_ids[i])))
2680- as Box<dyn Iterator<Item = AssociatedItem> + 'a>
2677+ ) -> AssociatedItemsIterator<'a, 'gcx, 'tcx> {
2678+ // Ideally, we would use `-> impl Iterator` here, but it falls
2679+ // afoul of the conservative "capture [restrictions]" we put
2680+ // in place, so we use a hand-written iterator.
2681+ //
2682+ // [restrictions]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999
2683+ AssociatedItemsIterator {
2684+ tcx: self,
2685+ def_ids: self.associated_item_def_ids(def_id),
2686+ next_index: 0,
2687+ }
26812688 }
26822689
26832690 /// 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> {
28742881 }
28752882}
28762883
2884+ pub struct AssociatedItemsIterator<'a, 'gcx: 'tcx, 'tcx: 'a> {
2885+ tcx: TyCtxt<'a, 'gcx, 'tcx>,
2886+ def_ids: Lrc<Vec<DefId>>,
2887+ next_index: usize,
2888+ }
2889+
2890+ impl Iterator for AssociatedItemsIterator<'_, '_, '_> {
2891+ type Item = AssociatedItem;
2892+
2893+ fn next(&mut self) -> Option<AssociatedItem> {
2894+ let def_id = self.def_ids.get(self.next_index)?;
2895+ self.next_index += 1;
2896+ Some(self.tcx.associated_item(*def_id))
2897+ }
2898+ }
2899+
28772900impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
28782901 pub fn with_freevars<T, F>(self, fid: NodeId, f: F) -> T where
28792902 F: FnOnce(&[hir::Freevar]) -> T,
0 commit comments