about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_lint/src/for_loop_over_fallibles.rs22
1 files changed, 14 insertions, 8 deletions
diff --git a/compiler/rustc_lint/src/for_loop_over_fallibles.rs b/compiler/rustc_lint/src/for_loop_over_fallibles.rs
index c96c9efe1d8..d765131442f 100644
--- a/compiler/rustc_lint/src/for_loop_over_fallibles.rs
+++ b/compiler/rustc_lint/src/for_loop_over_fallibles.rs
@@ -1,6 +1,7 @@
 use crate::{LateContext, LateLintPass, LintContext};
 
 use hir::{Expr, Pat};
+use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_middle::ty;
 use rustc_span::sym;
@@ -65,18 +66,24 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopOverFallibles {
             _ => return,
         };
 
-        let Ok(pat_snip) = cx.sess().source_map().span_to_snippet(pat.span) else { return };
         let Ok(arg_snip) = cx.sess().source_map().span_to_snippet(arg.span) else { return };
 
-        let help_string = format!(
-            "consider replacing `for {pat_snip} in {arg_snip}` with `if let {var}({pat_snip}) = {arg_snip}`"
-        );
         let msg = format!(
             "for loop over `{arg_snip}`, which is {article} `{ty}`. This is more readably written as an `if let` statement",
         );
 
         cx.struct_span_lint(FOR_LOOP_OVER_FALLIBLES, arg.span, |diag| {
-            diag.build(msg).help(help_string).emit()
+            diag.build(msg)
+                .multipart_suggestion_verbose(
+                    "consider using `if let` to clear intent",
+                    vec![
+                        // NB can't use `until` here because `expr.span` and `pat.span` have different syntax contexts
+                        (expr.span.with_hi(pat.span.lo()), format!("if let {var}(")),
+                        (pat.span.between(arg.span), format!(") = ")),
+                    ],
+                    Applicability::MachineApplicable,
+                )
+                .emit()
         })
     }
 }
@@ -89,11 +96,10 @@ fn extract_for_loop<'tcx>(expr: &Expr<'tcx>) -> Option<(&'tcx Pat<'tcx>, &'tcx E
     && let [stmt] = block.stmts
     && let hir::StmtKind::Expr(e) = stmt.kind
     && let hir::ExprKind::Match(_, [_, some_arm], _) = e.kind
-    && let hir::PatKind::Struct(_, [field], _) = some_arm.pat.kind 
+    && let hir::PatKind::Struct(_, [field], _) = some_arm.pat.kind
     {
         Some((field.pat, arg))
     } else {
         None
     }
-    
-}
\ No newline at end of file
+}