diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a1338dcd4771b..45c11fc9eb00d 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1810,18 +1810,27 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { false } - fn let_binding_suggestion(&self, err: &mut Diagnostic, ident_span: Span) -> bool { + fn let_binding_suggestion(&mut self, err: &mut Diagnostic, ident_span: Span) -> bool { // try to give a suggestion for this pattern: `name = 1`, which is common in other languages let mut added_suggestion = false; - if let Some(Expr { kind: ExprKind::Assign(lhs, _rhs, _), .. }) = self.diagnostic_metadata.in_assignment && - let ast::ExprKind::Path(None, _) = lhs.kind { + if let Some(Expr { kind: ExprKind::Assign(lhs, rhs, _), .. }) = + self.diagnostic_metadata.in_assignment + { + let is_rhs_assign = match rhs.kind { + ExprKind::Assign(..) => true, + _ => false, + }; + + if let ast::ExprKind::Path(None, _) = lhs.kind && !is_rhs_assign { let sm = self.r.session.source_map(); let line_span = sm.span_extend_to_line(ident_span); let ident_name = sm.span_to_snippet(ident_span).unwrap(); - // HACK(chenyukang): make sure ident_name is at the starting of the line to protect against macros - if sm - .span_to_snippet(line_span) - .map_or(false, |s| s.trim().starts_with(&ident_name)) + // HACK(chenyukang): make sure ident_name is at the starting of the line to protect against macros, + // and avoid some special cases like `x = x = x` + if let Ok(line) = sm.span_to_snippet(line_span) && + let stripped = line.split_whitespace().collect::() && + stripped.trim().starts_with(&ident_name) && + stripped.matches(&format!("{}=", &ident_name)).count() == 1 { err.span_suggestion_verbose( ident_span.shrink_to_lo(), @@ -1832,6 +1841,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { added_suggestion = true; } } + self.diagnostic_metadata.in_assignment = None; + } added_suggestion } diff --git a/src/test/ui/suggestions/issue-104086-suggest-let.rs b/src/test/ui/suggestions/issue-104086-suggest-let.rs new file mode 100644 index 0000000000000..e23109a3be69c --- /dev/null +++ b/src/test/ui/suggestions/issue-104086-suggest-let.rs @@ -0,0 +1,10 @@ +// error-pattern: not found in this scope + +fn main() { + x = x = x; + x = y = y = y; + x = y = y; + x = x = y; + x = x; // will suggest add `let` + x = y // will suggest add `let` +} diff --git a/src/test/ui/suggestions/issue-104086-suggest-let.stderr b/src/test/ui/suggestions/issue-104086-suggest-let.stderr new file mode 100644 index 0000000000000..2af9c142ec69e --- /dev/null +++ b/src/test/ui/suggestions/issue-104086-suggest-let.stderr @@ -0,0 +1,81 @@ +error[E0425]: cannot find value `x` in this scope + --> $DIR/issue-104086-suggest-let.rs:4:5 + | +LL | x = x = x; + | ^ not found in this scope + +error[E0425]: cannot find value `x` in this scope + --> $DIR/issue-104086-suggest-let.rs:4:9 + | +LL | x = x = x; + | ^ not found in this scope + +error[E0425]: cannot find value `x` in this scope + --> $DIR/issue-104086-suggest-let.rs:4:13 + | +LL | x = x = x; + | ^ not found in this scope + +error[E0425]: cannot find value `x` in this scope + --> $DIR/issue-104086-suggest-let.rs:5:5 + | +LL | x = y = y = y; + | ^ not found in this scope + +error[E0425]: cannot find value `y` in this scope + --> $DIR/issue-104086-suggest-let.rs:5:9 + | +LL | x = y = y = y; + | ^ not found in this scope + +error[E0425]: cannot find value `y` in this scope + --> $DIR/issue-104086-suggest-let.rs:5:13 + | +LL | x = y = y = y; + | ^ not found in this scope + +error[E0425]: cannot find value `y` in this scope + --> $DIR/issue-104086-suggest-let.rs:5:17 + | +LL | x = y = y = y; + | ^ not found in this scope + +error[E0425]: cannot find value `x` in this scope + --> $DIR/issue-104086-suggest-let.rs:6:5 + | +LL | x = y = y; + | ^ not found in this scope + +error[E0425]: cannot find value `y` in this scope + --> $DIR/issue-104086-suggest-let.rs:6:9 + | +LL | x = y = y; + | ^ not found in this scope + +error[E0425]: cannot find value `y` in this scope + --> $DIR/issue-104086-suggest-let.rs:6:13 + | +LL | x = y = y; + | ^ not found in this scope + +error[E0425]: cannot find value `x` in this scope + --> $DIR/issue-104086-suggest-let.rs:7:5 + | +LL | x = x = y; + | ^ not found in this scope + +error[E0425]: cannot find value `x` in this scope + --> $DIR/issue-104086-suggest-let.rs:7:9 + | +LL | x = x = y; + | ^ not found in this scope + +error[E0425]: cannot find value `y` in this scope + --> $DIR/issue-104086-suggest-let.rs:7:13 + | +LL | x = x = y; + | ^ not found in this scope + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0425`.