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