@@ -28,7 +28,6 @@ use rustc_span::{BytePos, Span, Symbol};
2828use  rustc_trait_selection:: infer:: InferCtxtExt ; 
2929use  rustc_trait_selection:: traits:: ObligationCtxt ; 
3030use  std:: iter; 
31- use  std:: marker:: PhantomData ; 
3231
3332use  crate :: borrow_set:: TwoPhaseActivation ; 
3433use  crate :: borrowck_errors; 
@@ -1305,12 +1304,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
13051304        let  hir = tcx. hir ( ) ; 
13061305
13071306        let  Some ( body_id)  = hir. get ( self . mir_hir_id ( ) ) . body_id ( )  else  {  return  } ; 
1307+         let  typeck_results = tcx. typeck ( self . mir_def_id ( ) ) ; 
13081308
13091309        struct  ExprFinder < ' hir >  { 
1310-             phantom :  PhantomData < & ' hir  hir:: Expr < ' hir > > , 
13111310            issue_span :  Span , 
13121311            expr_span :  Span , 
1313-             found_body_expr :   bool , 
1312+             body_expr :   Option < & ' hir  hir :: Expr < ' hir > > , 
13141313            loop_bind :  Option < Symbol > , 
13151314        } 
13161315        impl < ' hir >  Visitor < ' hir >  for  ExprFinder < ' hir >  { 
@@ -1326,30 +1325,28 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
13261325                        self . loop_bind  = Some ( ident. name ) ; 
13271326                    } 
13281327
1329-                 if  let  hir:: ExprKind :: MethodCall ( body_call,  ..)  = ex. kind  &&
1330-                     body_call. ident . name  == sym:: next &&
1331-                     ex. span . source_equal ( self . expr_span )  { 
1332-                         self . found_body_expr  = true ; 
1328+                 if  let  hir:: ExprKind :: MethodCall ( body_call,  _recv,  ..)  = ex. kind  &&
1329+                     body_call. ident . name  == sym:: next && ex. span . source_equal ( self . expr_span )  { 
1330+                         self . body_expr  = Some ( ex) ; 
13331331                } 
13341332
13351333                hir:: intravisit:: walk_expr ( self ,  ex) ; 
13361334            } 
13371335        } 
1338-         let  mut  finder = ExprFinder  { 
1339-             phantom :  PhantomData , 
1340-             expr_span :  span, 
1341-             issue_span, 
1342-             loop_bind :  None , 
1343-             found_body_expr :  false , 
1344-         } ; 
1336+         let  mut  finder =
1337+             ExprFinder  {  expr_span :  span,  issue_span,  loop_bind :  None ,  body_expr :  None  } ; 
13451338        finder. visit_expr ( hir. body ( body_id) . value ) ; 
1339+ 
13461340        if  let  Some ( loop_bind)  = finder. loop_bind  &&
1347-             finder. found_body_expr  { 
1348-             err. note ( format ! ( 
1349-                 "a for loop advances the iterator for you, the result is stored in `{}`." , 
1350-                 loop_bind
1351-             ) ) ; 
1352-             err. help ( "if you want to call `next` on a iterator within the loop, consider using `while let`." ) ; 
1341+             let  Some ( body_expr)  = finder. body_expr  &&
1342+                 let  Some ( def_id)  = typeck_results. type_dependent_def_id ( body_expr. hir_id )  &&
1343+                 let  Some ( trait_did)  = tcx. trait_of_item ( def_id)  &&
1344+                 tcx. is_diagnostic_item ( sym:: Iterator ,  trait_did)  { 
1345+                     err. note ( format ! ( 
1346+                         "a for loop advances the iterator for you, the result is stored in `{}`." , 
1347+                         loop_bind
1348+                     ) ) ; 
1349+                     err. help ( "if you want to call `next` on a iterator within the loop, consider using `while let`." ) ; 
13531350        } 
13541351    } 
13551352
0 commit comments