Skip to content

Commit 952df48

Browse files
committed
Fix #104086, Tighten the 'introduce new binding' suggestion
1 parent bc2504a commit 952df48

File tree

3 files changed

+109
-7
lines changed

3 files changed

+109
-7
lines changed

compiler/rustc_resolve/src/late/diagnostics.rs

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

1813-
fn let_binding_suggestion(&self, err: &mut Diagnostic, ident_span: Span) -> bool {
1813+
fn let_binding_suggestion(&mut self, err: &mut Diagnostic, ident_span: Span) -> bool {
18141814
// try to give a suggestion for this pattern: `name = 1`, which is common in other languages
18151815
let mut added_suggestion = false;
1816-
if let Some(Expr { kind: ExprKind::Assign(lhs, _rhs, _), .. }) = self.diagnostic_metadata.in_assignment &&
1817-
let ast::ExprKind::Path(None, _) = lhs.kind {
1816+
if let Some(Expr { kind: ExprKind::Assign(lhs, rhs, _), .. }) =
1817+
self.diagnostic_metadata.in_assignment
1818+
{
1819+
let is_rhs_assign = match rhs.kind {
1820+
ExprKind::Assign(..) => true,
1821+
_ => false,
1822+
};
1823+
1824+
if let ast::ExprKind::Path(None, _) = lhs.kind && !is_rhs_assign {
18181825
let sm = self.r.session.source_map();
18191826
let line_span = sm.span_extend_to_line(ident_span);
18201827
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))
1828+
// HACK(chenyukang): make sure ident_name is at the starting of the line to protect against macros,
1829+
// and avoid some special cases like `x = x = x`
1830+
if let Ok(line) = sm.span_to_snippet(line_span) &&
1831+
let stripped = line.split_whitespace().collect::<String>() &&
1832+
stripped.trim().starts_with(&ident_name) &&
1833+
stripped.matches(&format!("{}=", &ident_name)).count() == 1
18251834
{
18261835
err.span_suggestion_verbose(
18271836
ident_span.shrink_to_lo(),
@@ -1832,6 +1841,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
18321841
added_suggestion = true;
18331842
}
18341843
}
1844+
self.diagnostic_metadata.in_assignment = None;
1845+
}
18351846
added_suggestion
18361847
}
18371848

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// error-pattern: not found in this scope
2+
3+
fn main() {
4+
x = x = x;
5+
x = y = y = y;
6+
x = y = y;
7+
x = x = y;
8+
x = x; // will suggest add `let`
9+
x = y // will suggest add `let`
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
error[E0425]: cannot find value `x` in this scope
2+
--> $DIR/issue-104086-suggest-let.rs:4:5
3+
|
4+
LL | x = x = x;
5+
| ^ not found in this scope
6+
7+
error[E0425]: cannot find value `x` in this scope
8+
--> $DIR/issue-104086-suggest-let.rs:4:9
9+
|
10+
LL | x = x = x;
11+
| ^ not found in this scope
12+
13+
error[E0425]: cannot find value `x` in this scope
14+
--> $DIR/issue-104086-suggest-let.rs:4:13
15+
|
16+
LL | x = x = x;
17+
| ^ not found in this scope
18+
19+
error[E0425]: cannot find value `x` in this scope
20+
--> $DIR/issue-104086-suggest-let.rs:5:5
21+
|
22+
LL | x = y = y = y;
23+
| ^ not found in this scope
24+
25+
error[E0425]: cannot find value `y` in this scope
26+
--> $DIR/issue-104086-suggest-let.rs:5:9
27+
|
28+
LL | x = y = y = y;
29+
| ^ not found in this scope
30+
31+
error[E0425]: cannot find value `y` in this scope
32+
--> $DIR/issue-104086-suggest-let.rs:5:13
33+
|
34+
LL | x = y = y = y;
35+
| ^ not found in this scope
36+
37+
error[E0425]: cannot find value `y` in this scope
38+
--> $DIR/issue-104086-suggest-let.rs:5:17
39+
|
40+
LL | x = y = y = y;
41+
| ^ not found in this scope
42+
43+
error[E0425]: cannot find value `x` in this scope
44+
--> $DIR/issue-104086-suggest-let.rs:6:5
45+
|
46+
LL | x = y = y;
47+
| ^ not found in this scope
48+
49+
error[E0425]: cannot find value `y` in this scope
50+
--> $DIR/issue-104086-suggest-let.rs:6:9
51+
|
52+
LL | x = y = y;
53+
| ^ not found in this scope
54+
55+
error[E0425]: cannot find value `y` in this scope
56+
--> $DIR/issue-104086-suggest-let.rs:6:13
57+
|
58+
LL | x = y = y;
59+
| ^ not found in this scope
60+
61+
error[E0425]: cannot find value `x` in this scope
62+
--> $DIR/issue-104086-suggest-let.rs:7:5
63+
|
64+
LL | x = x = y;
65+
| ^ not found in this scope
66+
67+
error[E0425]: cannot find value `x` in this scope
68+
--> $DIR/issue-104086-suggest-let.rs:7:9
69+
|
70+
LL | x = x = y;
71+
| ^ not found in this scope
72+
73+
error[E0425]: cannot find value `y` in this scope
74+
--> $DIR/issue-104086-suggest-let.rs:7:13
75+
|
76+
LL | x = x = y;
77+
| ^ not found in this scope
78+
79+
error: aborting due to 13 previous errors
80+
81+
For more information about this error, try `rustc --explain E0425`.

0 commit comments

Comments
 (0)