@@ -2674,10 +2674,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
2674
2674
pub fn associated_items (
2675
2675
self ,
2676
2676
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
+ }
2681
2688
}
2682
2689
2683
2690
/// 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> {
2874
2881
}
2875
2882
}
2876
2883
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
+
2877
2900
impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
2878
2901
pub fn with_freevars < T , F > ( self , fid : NodeId , f : F ) -> T where
2879
2902
F : FnOnce ( & [ hir:: Freevar ] ) -> T ,
0 commit comments