@@ -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