about summary refs log tree commit diff
path: root/compiler/rustc_resolve/src/late
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2025-02-11 22:16:07 +0800
committeryukang <moorekang@gmail.com>2025-02-12 09:56:07 +0800
commita917fd5f98913a04b839cccca43558f4e4fc831b (patch)
treee60d1870aa90a1e0f7de5bb75a25adf675a99f66 /compiler/rustc_resolve/src/late
parentffa9afef183a3496a277c8da2e61403582a99508 (diff)
Fix diagnostic when using = instead of : in let bindings
Diffstat (limited to 'compiler/rustc_resolve/src/late')
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs23
1 files changed, 22 insertions, 1 deletions
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index a80b68d9773..0962865e7f1 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -2347,9 +2347,14 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
     // try to give a suggestion for this pattern: `name = blah`, which is common in other languages
     // suggest `let name = blah` to introduce a new binding
     fn let_binding_suggestion(&mut self, err: &mut Diag<'_>, ident_span: Span) -> bool {
+        if ident_span.from_expansion() {
+            return false;
+        }
+
+        // only suggest when the code is a assignment without prefix code
         if let Some(Expr { kind: ExprKind::Assign(lhs, ..), .. }) = self.diag_metadata.in_assignment
             && let ast::ExprKind::Path(None, ref path) = lhs.kind
-            && !ident_span.from_expansion()
+            && self.r.tcx.sess.source_map().is_line_before_span_empty(ident_span)
         {
             let (span, text) = match path.segments.first() {
                 Some(seg) if let Some(name) = seg.ident.as_str().strip_prefix("let") => {
@@ -2368,6 +2373,22 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
             );
             return true;
         }
+
+        // a special case for #133713
+        // '=' maybe a typo of `:`, which is a type annotation instead of assignment
+        if err.code == Some(E0423)
+            && let Some((let_span, None, Some(val_span))) = self.diag_metadata.current_let_binding
+            && val_span.contains(ident_span)
+            && val_span.lo() == ident_span.lo()
+        {
+            err.span_suggestion_verbose(
+                let_span.shrink_to_hi().to(val_span.shrink_to_lo()),
+                "you might have meant to use `:` for type annotation",
+                ": ",
+                Applicability::MaybeIncorrect,
+            );
+            return true;
+        }
         false
     }