Rollup merge of #104186 - chenyukang:yukang/fix-104086-let-binding-issue, r=oli-obk
Tighten the 'introduce new binding' suggestion Fixes #104086
This commit is contained in:
commit
819c9315c3
4 changed files with 182 additions and 18 deletions
|
@ -527,6 +527,7 @@ struct DiagnosticMetadata<'ast> {
|
|||
|
||||
/// Used to detect possible new binding written without `let` and to provide structured suggestion.
|
||||
in_assignment: Option<&'ast Expr>,
|
||||
is_assign_rhs: bool,
|
||||
|
||||
/// If we are currently in a trait object definition. Used to point at the bounds when
|
||||
/// encountering a struct or enum.
|
||||
|
@ -3963,10 +3964,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
self.resolve_expr(elem, Some(expr));
|
||||
self.visit_expr(idx);
|
||||
}
|
||||
ExprKind::Assign(..) => {
|
||||
let old = self.diagnostic_metadata.in_assignment.replace(expr);
|
||||
visit::walk_expr(self, expr);
|
||||
self.diagnostic_metadata.in_assignment = old;
|
||||
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;
|
||||
}
|
||||
_ => {
|
||||
visit::walk_expr(self, expr);
|
||||
|
|
|
@ -1810,29 +1810,22 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
|||
false
|
||||
}
|
||||
|
||||
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 &&
|
||||
// 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 &&
|
||||
let ast::ExprKind::Path(None, _) = lhs.kind {
|
||||
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))
|
||||
{
|
||||
if !ident_span.from_expansion() {
|
||||
err.span_suggestion_verbose(
|
||||
ident_span.shrink_to_lo(),
|
||||
"you might have meant to introduce a new binding",
|
||||
"let ".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
added_suggestion = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
added_suggestion
|
||||
false
|
||||
}
|
||||
|
||||
fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> {
|
||||
|
|
30
src/test/ui/suggestions/issue-104086-suggest-let.rs
Normal file
30
src/test/ui/suggestions/issue-104086-suggest-let.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
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
|
||||
}
|
135
src/test/ui/suggestions/issue-104086-suggest-let.stderr
Normal file
135
src/test/ui/suggestions/issue-104086-suggest-let.stderr
Normal file
|
@ -0,0 +1,135 @@
|
|||
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`.
|
Loading…
Add table
Reference in a new issue