Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. If you cannot produce a minimal reproduction case (something that would work in isolation), please provide the steps or even link to a repository that causes the problematic output to occur. --Given the following code: The current output is: <!-- The following is not always necessary. --Ideally the output should first check the RHS, before suggest adding . It should also avoid suggesting when code is invalid. Thanks. Something like this should also not suggest adding : cc <!-- If the problem is not self-explanatory, please provide a rationale for the change. --<!-- If dramatically different output is caused by small changes, consider also adding them here. If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. The output might also be different depending on the Edition. --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I'm not convinced the second example should be something we need to fix, but the first example should be very easy to fix.
claim

Discussion:
/// Used to detect possible new binding written without `let` and to provide structured suggestion. in_assignment: Option<&'ast Expr>, <ins> is_assign_rhs: bool, </ins> /// If we are currently in a trait object definition. Used to point at the bounds when /// encountering a struct or enum.

self.resolve_expr(elem, Some(expr)); self.visit_expr(idx); } <del> ExprKind::Assign(..) => { let old = self.diagnostic_metadata.in_assignment.replace(expr); visit::walk_expr(self, expr); self.diagnostic_metadata.in_assignment = old; </del> <ins> ExprKind::Assign(ref lhs, ref rhs, _) => { if !self.diagnostic_metadata.is_assign_rhs { self.diagnostic_metadata.in_assignment = Some(expr); } self.visit_expr(lhs); self.diagnostic_metadata.is_assign_rhs = true; self.diagnostic_metadata.in_assignment = None; self.visit_expr(rhs); self.diagnostic_metadata.is_assign_rhs = false; </ins> } _ => { visit::walk_expr(self, expr);

false } <del> fn let_binding_suggestion(&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 && </del> <ins> // 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 Diagnostic, ident_span: Span) -> bool { if let Some(Expr { kind: ExprKind::Assign(lhs, .. ), .. }) = self.diagnostic_metadata.in_assignment && </ins> let ast::ExprKind::Path(None, _) = lhs.kind { <del> 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)) { </del> <ins> if !ident_span.from_expansion() { </ins> err.span_suggestion_verbose( ident_span.shrink_to_lo(), "you might have meant to introduce a new binding", "let ".to_string(), Applicability::MaybeIncorrect, ); <del> added_suggestion = true; </del> <ins> return true; </ins> } } <del> added_suggestion </del> <ins> false </ins> } fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> {

<ins> fn main() { x = x = x; //~^ ERROR cannot find value `x` in this scope //~| ERROR cannot find value `x` in this scope //~| ERROR cannot find value `x` in this scope x = y = y = y; //~^ ERROR cannot find value `y` in this scope //~| ERROR cannot find value `y` in this scope //~| ERROR cannot find value `y` in this scope //~| ERROR cannot find value `x` in this scope x = y = y; //~^ ERROR cannot find value `x` in this scope //~| ERROR cannot find value `y` in this scope //~| ERROR cannot find value `y` in this scope x = x = y; //~^ ERROR cannot find value `x` in this scope //~| ERROR cannot find value `x` in this scope //~| ERROR cannot find value `y` in this scope x = x; // will suggest add `let` //~^ ERROR cannot find value `x` in this scope //~| ERROR cannot find value `x` in this scope x = y // will suggest add `let` //~^ ERROR cannot find value `x` in this scope //~| ERROR cannot find value `y` in this scope } </ins>

<ins> error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:2:5 | LL |     x = x = x; |     ^ | help: you might have meant to introduce a new binding | LL |     let x = x = x; |     +++ error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:2: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:2: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:7:5 | LL |     x = y = y = y; |     ^ | help: you might have meant to introduce a new binding | LL |     let x = y = y = y; |     +++ error[E0425]: cannot find value `y` in this scope --> $DIR/issue-104086-suggest-let.rs:7: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:7: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:7: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:13:5 | LL |     x = y = y; |     ^ | help: you might have meant to introduce a new binding | LL |     let x = y = y; |     +++ error[E0425]: cannot find value `y` in this scope --> $DIR/issue-104086-suggest-let.rs:13: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:13: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:18:5 | LL |     x = x = y; |     ^ | help: you might have meant to introduce a new binding | LL |     let x = x = y; |     +++ error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:18: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:18:13 | LL |     x = x = y; |             ^ not found in this scope error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:23:5 | LL |     x = x; // will suggest add `let` |     ^ | help: you might have meant to introduce a new binding | LL |     let x = x; // will suggest add `let` |     +++ error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:23:9 | LL |     x = x; // will suggest add `let` |         ^ not found in this scope error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:27:5 | LL |     x = y // will suggest add `let` |     ^ | help: you might have meant to introduce a new binding | LL |     let x = y // will suggest add `let` |     +++ error[E0425]: cannot find value `y` in this scope --> $DIR/issue-104086-suggest-let.rs:27:9 | LL |     x = y // will suggest add `let` |         ^ not found in this scope error: aborting due to 17 previous errors For more information about this error, try `rustc --explain E0425`. </ins>