about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJubilee <workingjubilee@gmail.com>2025-02-13 17:46:08 -0800
committerGitHub <noreply@github.com>2025-02-13 17:46:08 -0800
commitd784803115ee2226e22d10f7ad6dede618aa8dd7 (patch)
tree695d9c1effea9900d5a2b0e0c86fa8f915f08786
parente2ee9f73189de5b64012fd9ce2ae4e1411db0ed4 (diff)
parenta917fd5f98913a04b839cccca43558f4e4fc831b (diff)
downloadrust-d784803115ee2226e22d10f7ad6dede618aa8dd7.tar.gz
rust-d784803115ee2226e22d10f7ad6dede618aa8dd7.zip
Rollup merge of #136869 - chenyukang:yukang-fix-133713-let-binding, r=estebank
Fix diagnostic when using = instead of : in let binding

Fixes #133713

r? ``@estebank``
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs23
-rw-r--r--tests/ui/suggestions/let-binding-suggest-issue-133713.fixed12
-rw-r--r--tests/ui/suggestions/let-binding-suggest-issue-133713.rs12
-rw-r--r--tests/ui/suggestions/let-binding-suggest-issue-133713.stderr27
4 files changed, 73 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
     }
 
diff --git a/tests/ui/suggestions/let-binding-suggest-issue-133713.fixed b/tests/ui/suggestions/let-binding-suggest-issue-133713.fixed
new file mode 100644
index 00000000000..9f9c1d1bc5a
--- /dev/null
+++ b/tests/ui/suggestions/let-binding-suggest-issue-133713.fixed
@@ -0,0 +1,12 @@
+//@ run-rustfix
+#![allow(dead_code)]
+
+fn demo1() {
+    let _last: u64 = 0; //~ ERROR expected value, found builtin type `u64`
+}
+
+fn demo2() {
+    let _val: u64; //~ ERROR expected value, found builtin type `u64`
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/let-binding-suggest-issue-133713.rs b/tests/ui/suggestions/let-binding-suggest-issue-133713.rs
new file mode 100644
index 00000000000..ae218237a8d
--- /dev/null
+++ b/tests/ui/suggestions/let-binding-suggest-issue-133713.rs
@@ -0,0 +1,12 @@
+//@ run-rustfix
+#![allow(dead_code)]
+
+fn demo1() {
+    let _last = u64 = 0; //~ ERROR expected value, found builtin type `u64`
+}
+
+fn demo2() {
+    let _val = u64; //~ ERROR expected value, found builtin type `u64`
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/let-binding-suggest-issue-133713.stderr b/tests/ui/suggestions/let-binding-suggest-issue-133713.stderr
new file mode 100644
index 00000000000..185ad9c928b
--- /dev/null
+++ b/tests/ui/suggestions/let-binding-suggest-issue-133713.stderr
@@ -0,0 +1,27 @@
+error[E0423]: expected value, found builtin type `u64`
+  --> $DIR/let-binding-suggest-issue-133713.rs:5:17
+   |
+LL |     let _last = u64 = 0;
+   |                 ^^^
+   |
+help: you might have meant to use `:` for type annotation
+   |
+LL -     let _last = u64 = 0;
+LL +     let _last: u64 = 0;
+   |
+
+error[E0423]: expected value, found builtin type `u64`
+  --> $DIR/let-binding-suggest-issue-133713.rs:9:16
+   |
+LL |     let _val = u64;
+   |                ^^^
+   |
+help: you might have meant to use `:` for type annotation
+   |
+LL -     let _val = u64;
+LL +     let _val: u64;
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0423`.