about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_lint/src/for_loops_over_fallibles.rs12
-rw-r--r--tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs10
-rw-r--r--tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr24
3 files changed, 41 insertions, 5 deletions
diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
index 757fc1f58bd..a56b753bda7 100644
--- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs
+++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
@@ -49,6 +49,8 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         let Some((pat, arg)) = extract_for_loop(expr) else { return };
 
+        let arg_span = arg.span.source_callsite();
+
         let ty = cx.typeck_results().expr_ty(arg);
 
         let (adt, args, ref_mutability) = match ty.kind() {
@@ -78,27 +80,27 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
             && let Ok(recv_snip) = cx.sess().source_map().span_to_snippet(recv.span)
         {
             ForLoopsOverFalliblesLoopSub::RemoveNext {
-                suggestion: recv.span.between(arg.span.shrink_to_hi()),
+                suggestion: recv.span.between(arg_span.shrink_to_hi()),
                 recv_snip,
             }
         } else {
             ForLoopsOverFalliblesLoopSub::UseWhileLet {
                 start_span: expr.span.with_hi(pat.span.lo()),
-                end_span: pat.span.between(arg.span),
+                end_span: pat.span.between(arg_span),
                 var,
             }
         };
         let question_mark = suggest_question_mark(cx, adt, args, expr.span)
-            .then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() });
+            .then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg_span.shrink_to_hi() });
         let suggestion = ForLoopsOverFalliblesSuggestion {
             var,
             start_span: expr.span.with_hi(pat.span.lo()),
-            end_span: pat.span.between(arg.span),
+            end_span: pat.span.between(arg_span),
         };
 
         cx.emit_span_lint(
             FOR_LOOPS_OVER_FALLIBLES,
-            arg.span,
+            arg_span,
             ForLoopsOverFalliblesDiag { article, ref_prefix, ty, sub, question_mark, suggestion },
         );
     }
diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs
new file mode 100644
index 00000000000..33a89ced963
--- /dev/null
+++ b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs
@@ -0,0 +1,10 @@
+#![forbid(for_loops_over_fallibles)]
+
+fn main() {
+    macro_rules! x {
+        () => {
+            None::<i32>
+        };
+    }
+    for _ in x! {} {} //~ ERROR for loop over an `Option`. This is more readably written as an `if let` statement [for_loops_over_fallibles]
+}
diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr
new file mode 100644
index 00000000000..550d26045fb
--- /dev/null
+++ b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr
@@ -0,0 +1,24 @@
+error: for loop over an `Option`. This is more readably written as an `if let` statement
+  --> $DIR/macro-issue-140747.rs:9:14
+   |
+LL |     for _ in x! {} {}
+   |              ^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/macro-issue-140747.rs:1:11
+   |
+LL | #![forbid(for_loops_over_fallibles)]
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^
+help: to check pattern in a loop use `while let`
+   |
+LL -     for _ in x! {} {}
+LL +     while let Some(_) = x! {} {}
+   |
+help: consider using `if let` to clear intent
+   |
+LL -     for _ in x! {} {}
+LL +     if let Some(_) = x! {} {}
+   |
+
+error: aborting due to 1 previous error
+