Skip to content

Commit 4189faa

Browse files
committed
add typecheck for iterator
1 parent 44a8a8d commit 4189faa

File tree

1 file changed

+17
-20
lines changed

1 file changed

+17
-20
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+17-20
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ use rustc_span::{BytePos, Span, Symbol};
2828
use rustc_trait_selection::infer::InferCtxtExt;
2929
use rustc_trait_selection::traits::ObligationCtxt;
3030
use std::iter;
31-
use std::marker::PhantomData;
3231

3332
use crate::borrow_set::TwoPhaseActivation;
3433
use 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

Comments
 (0)