@@ -28,7 +28,6 @@ use rustc_span::{BytePos, Span, Symbol};
28
28
use rustc_trait_selection:: infer:: InferCtxtExt ;
29
29
use rustc_trait_selection:: traits:: ObligationCtxt ;
30
30
use std:: iter;
31
- use std:: marker:: PhantomData ;
32
31
33
32
use crate :: borrow_set:: TwoPhaseActivation ;
34
33
use crate :: borrowck_errors;
@@ -1305,12 +1304,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
1305
1304
let hir = tcx. hir ( ) ;
1306
1305
1307
1306
let Some ( body_id) = hir. get ( self . mir_hir_id ( ) ) . body_id ( ) else { return } ;
1307
+ let typeck_results = tcx. typeck ( self . mir_def_id ( ) ) ;
1308
1308
1309
1309
struct ExprFinder < ' hir > {
1310
- phantom : PhantomData < & ' hir hir:: Expr < ' hir > > ,
1311
1310
issue_span : Span ,
1312
1311
expr_span : Span ,
1313
- found_body_expr : bool ,
1312
+ body_expr : Option < & ' hir hir :: Expr < ' hir > > ,
1314
1313
loop_bind : Option < Symbol > ,
1315
1314
}
1316
1315
impl < ' hir > Visitor < ' hir > for ExprFinder < ' hir > {
@@ -1326,30 +1325,28 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
1326
1325
self . loop_bind = Some ( ident. name ) ;
1327
1326
}
1328
1327
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) ;
1333
1331
}
1334
1332
1335
1333
hir:: intravisit:: walk_expr ( self , ex) ;
1336
1334
}
1337
1335
}
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 } ;
1345
1338
finder. visit_expr ( hir. body ( body_id) . value ) ;
1339
+
1346
1340
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`." ) ;
1353
1350
}
1354
1351
}
1355
1352
0 commit comments