diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a80b68d9773d4..0962865e7f190 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 0000000000000..9f9c1d1bc5aa1 --- /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 0000000000000..ae218237a8d5c --- /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 0000000000000..185ad9c928b48 --- /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`.