Skip to content

Commit 819c931

Browse files
authored
Rollup merge of #104186 - chenyukang:yukang/fix-104086-let-binding-issue, r=oli-obk
Tighten the 'introduce new binding' suggestion Fixes #104086
2 parents 8f2c1f8 + c69872b commit 819c931

File tree

4 files changed

+182
-18
lines changed

4 files changed

+182
-18
lines changed

compiler/rustc_resolve/src/late.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ struct DiagnosticMetadata<'ast> {
527527

528528
/// Used to detect possible new binding written without `let` and to provide structured suggestion.
529529
in_assignment: Option<&'ast Expr>,
530+
is_assign_rhs: bool,
530531

531532
/// If we are currently in a trait object definition. Used to point at the bounds when
532533
/// encountering a struct or enum.
@@ -3963,10 +3964,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
39633964
self.resolve_expr(elem, Some(expr));
39643965
self.visit_expr(idx);
39653966
}
3966-
ExprKind::Assign(..) => {
3967-
let old = self.diagnostic_metadata.in_assignment.replace(expr);
3968-
visit::walk_expr(self, expr);
3969-
self.diagnostic_metadata.in_assignment = old;
3967+
ExprKind::Assign(ref lhs, ref rhs, _) => {
3968+
if !self.diagnostic_metadata.is_assign_rhs {
3969+
self.diagnostic_metadata.in_assignment = Some(expr);
3970+
}
3971+
self.visit_expr(lhs);
3972+
self.diagnostic_metadata.is_assign_rhs = true;
3973+
self.diagnostic_metadata.in_assignment = None;
3974+
self.visit_expr(rhs);
3975+
self.diagnostic_metadata.is_assign_rhs = false;
39703976
}
39713977
_ => {
39723978
visit::walk_expr(self, expr);

compiler/rustc_resolve/src/late/diagnostics.rs

+7-14
Original file line numberDiff line numberDiff line change
@@ -1810,29 +1810,22 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
18101810
false
18111811
}
18121812

1813-
fn let_binding_suggestion(&self, err: &mut Diagnostic, ident_span: Span) -> bool {
1814-
// try to give a suggestion for this pattern: `name = 1`, which is common in other languages
1815-
let mut added_suggestion = false;
1816-
if let Some(Expr { kind: ExprKind::Assign(lhs, _rhs, _), .. }) = self.diagnostic_metadata.in_assignment &&
1813+
// try to give a suggestion for this pattern: `name = blah`, which is common in other languages
1814+
// suggest `let name = blah` to introduce a new binding
1815+
fn let_binding_suggestion(&mut self, err: &mut Diagnostic, ident_span: Span) -> bool {
1816+
if let Some(Expr { kind: ExprKind::Assign(lhs, .. ), .. }) = self.diagnostic_metadata.in_assignment &&
18171817
let ast::ExprKind::Path(None, _) = lhs.kind {
1818-
let sm = self.r.session.source_map();
1819-
let line_span = sm.span_extend_to_line(ident_span);
1820-
let ident_name = sm.span_to_snippet(ident_span).unwrap();
1821-
// HACK(chenyukang): make sure ident_name is at the starting of the line to protect against macros
1822-
if sm
1823-
.span_to_snippet(line_span)
1824-
.map_or(false, |s| s.trim().starts_with(&ident_name))
1825-
{
1818+
if !ident_span.from_expansion() {
18261819
err.span_suggestion_verbose(
18271820
ident_span.shrink_to_lo(),
18281821
"you might have meant to introduce a new binding",
18291822
"let ".to_string(),
18301823
Applicability::MaybeIncorrect,
18311824
);
1832-
added_suggestion = true;
1825+
return true;
18331826
}
18341827
}
1835-
added_suggestion
1828+
false
18361829
}
18371830

18381831
fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
fn main() {
2+
x = x = x;
3+
//~^ ERROR cannot find value `x` in this scope
4+
//~| ERROR cannot find value `x` in this scope
5+
//~| ERROR cannot find value `x` in this scope
6+
7+
x = y = y = y;
8+
//~^ ERROR cannot find value `y` in this scope
9+
//~| ERROR cannot find value `y` in this scope
10+
//~| ERROR cannot find value `y` in this scope
11+
//~| ERROR cannot find value `x` in this scope
12+
13+
x = y = y;
14+
//~^ ERROR cannot find value `x` in this scope
15+
//~| ERROR cannot find value `y` in this scope
16+
//~| ERROR cannot find value `y` in this scope
17+
18+
x = x = y;
19+
//~^ ERROR cannot find value `x` in this scope
20+
//~| ERROR cannot find value `x` in this scope
21+
//~| ERROR cannot find value `y` in this scope
22+
23+
x = x; // will suggest add `let`
24+
//~^ ERROR cannot find value `x` in this scope
25+
//~| ERROR cannot find value `x` in this scope
26+
27+
x = y // will suggest add `let`
28+
//~^ ERROR cannot find value `x` in this scope
29+
//~| ERROR cannot find value `y` in this scope
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
error[E0425]: cannot find value `x` in this scope
2+
--> $DIR/issue-104086-suggest-let.rs:2:5
3+
|
4+
LL | x = x = x;
5+
| ^
6+
|
7+
help: you might have meant to introduce a new binding
8+
|
9+
LL | let x = x = x;
10+
| +++
11+
12+
error[E0425]: cannot find value `x` in this scope
13+
--> $DIR/issue-104086-suggest-let.rs:2:9
14+
|
15+
LL | x = x = x;
16+
| ^ not found in this scope
17+
18+
error[E0425]: cannot find value `x` in this scope
19+
--> $DIR/issue-104086-suggest-let.rs:2:13
20+
|
21+
LL | x = x = x;
22+
| ^ not found in this scope
23+
24+
error[E0425]: cannot find value `x` in this scope
25+
--> $DIR/issue-104086-suggest-let.rs:7:5
26+
|
27+
LL | x = y = y = y;
28+
| ^
29+
|
30+
help: you might have meant to introduce a new binding
31+
|
32+
LL | let x = y = y = y;
33+
| +++
34+
35+
error[E0425]: cannot find value `y` in this scope
36+
--> $DIR/issue-104086-suggest-let.rs:7:9
37+
|
38+
LL | x = y = y = y;
39+
| ^ not found in this scope
40+
41+
error[E0425]: cannot find value `y` in this scope
42+
--> $DIR/issue-104086-suggest-let.rs:7:13
43+
|
44+
LL | x = y = y = y;
45+
| ^ not found in this scope
46+
47+
error[E0425]: cannot find value `y` in this scope
48+
--> $DIR/issue-104086-suggest-let.rs:7:17
49+
|
50+
LL | x = y = y = y;
51+
| ^ not found in this scope
52+
53+
error[E0425]: cannot find value `x` in this scope
54+
--> $DIR/issue-104086-suggest-let.rs:13:5
55+
|
56+
LL | x = y = y;
57+
| ^
58+
|
59+
help: you might have meant to introduce a new binding
60+
|
61+
LL | let x = y = y;
62+
| +++
63+
64+
error[E0425]: cannot find value `y` in this scope
65+
--> $DIR/issue-104086-suggest-let.rs:13:9
66+
|
67+
LL | x = y = y;
68+
| ^ not found in this scope
69+
70+
error[E0425]: cannot find value `y` in this scope
71+
--> $DIR/issue-104086-suggest-let.rs:13:13
72+
|
73+
LL | x = y = y;
74+
| ^ not found in this scope
75+
76+
error[E0425]: cannot find value `x` in this scope
77+
--> $DIR/issue-104086-suggest-let.rs:18:5
78+
|
79+
LL | x = x = y;
80+
| ^
81+
|
82+
help: you might have meant to introduce a new binding
83+
|
84+
LL | let x = x = y;
85+
| +++
86+
87+
error[E0425]: cannot find value `x` in this scope
88+
--> $DIR/issue-104086-suggest-let.rs:18:9
89+
|
90+
LL | x = x = y;
91+
| ^ not found in this scope
92+
93+
error[E0425]: cannot find value `y` in this scope
94+
--> $DIR/issue-104086-suggest-let.rs:18:13
95+
|
96+
LL | x = x = y;
97+
| ^ not found in this scope
98+
99+
error[E0425]: cannot find value `x` in this scope
100+
--> $DIR/issue-104086-suggest-let.rs:23:5
101+
|
102+
LL | x = x; // will suggest add `let`
103+
| ^
104+
|
105+
help: you might have meant to introduce a new binding
106+
|
107+
LL | let x = x; // will suggest add `let`
108+
| +++
109+
110+
error[E0425]: cannot find value `x` in this scope
111+
--> $DIR/issue-104086-suggest-let.rs:23:9
112+
|
113+
LL | x = x; // will suggest add `let`
114+
| ^ not found in this scope
115+
116+
error[E0425]: cannot find value `x` in this scope
117+
--> $DIR/issue-104086-suggest-let.rs:27:5
118+
|
119+
LL | x = y // will suggest add `let`
120+
| ^
121+
|
122+
help: you might have meant to introduce a new binding
123+
|
124+
LL | let x = y // will suggest add `let`
125+
| +++
126+
127+
error[E0425]: cannot find value `y` in this scope
128+
--> $DIR/issue-104086-suggest-let.rs:27:9
129+
|
130+
LL | x = y // will suggest add `let`
131+
| ^ not found in this scope
132+
133+
error: aborting due to 17 previous errors
134+
135+
For more information about this error, try `rustc --explain E0425`.

0 commit comments

Comments
 (0)