Suggest 'a when given a only when appropriate

When encountering a name `a` that isn't resolved, but a label `'a` is
found in the current ribs, only suggest `'a` if this name is the value
expression of a `break` statement.

Solve FIXME.
This commit is contained in:
Esteban Küber 2021-01-19 17:51:48 -08:00
parent 707ce2b798
commit a701ff981d
4 changed files with 46 additions and 30 deletions

View file

@ -2266,6 +2266,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
visit::walk_expr(self, expr); visit::walk_expr(self, expr);
} }
ExprKind::Break(None, Some(ref e)) => {
// We use this instead of `visit::walk_expr` to keep the parent expr around for
// better
self.resolve_expr(e, Some(&expr));
}
ExprKind::Let(ref pat, ref scrutinee) => { ExprKind::Let(ref pat, ref scrutinee) => {
self.visit_expr(scrutinee); self.visit_expr(scrutinee);
self.resolve_pattern_top(pat, PatternSource::Let); self.resolve_pattern_top(pat, PatternSource::Let);

View file

@ -547,15 +547,19 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
for label_rib in &self.label_ribs { for label_rib in &self.label_ribs {
for (label_ident, _) in &label_rib.bindings { for (label_ident, _) in &label_rib.bindings {
if format!("'{}", ident) == label_ident.to_string() { if format!("'{}", ident) == label_ident.to_string() {
let msg = "a label with a similar name exists"; err.span_label(label_ident.span, "a label with a similar name exists");
// FIXME: consider only emitting this suggestion if a label would be valid here if let PathSource::Expr(Some(Expr {
// which is pretty much only the case for `break` expressions. kind: ExprKind::Break(None, Some(_)),
err.span_suggestion( ..
span, })) = source
&msg, {
label_ident.name.to_string(), err.span_suggestion(
Applicability::MaybeIncorrect, span,
); "use the similarly named label",
label_ident.name.to_string(),
Applicability::MaybeIncorrect,
);
}
} }
} }
} }

View file

@ -1,74 +1,78 @@
error[E0425]: cannot find value `LOOP` in this scope error[E0425]: cannot find value `LOOP` in this scope
--> $DIR/label_misspelled.rs:3:9 --> $DIR/label_misspelled.rs:3:9
| |
LL | 'LOOP: loop {
| ----- a label with a similar name exists
LL | LOOP; LL | LOOP;
| ^^^^ | ^^^^ not found in this scope
| |
| not found in this scope
| help: a label with a similar name exists: `'LOOP`
error[E0425]: cannot find value `while_loop` in this scope error[E0425]: cannot find value `while_loop` in this scope
--> $DIR/label_misspelled.rs:7:9 --> $DIR/label_misspelled.rs:7:9
| |
LL | 'while_loop: while true {
| ----------- a label with a similar name exists
LL | while_loop; LL | while_loop;
| ^^^^^^^^^^ | ^^^^^^^^^^ not found in this scope
| |
| not found in this scope
| help: a label with a similar name exists: `'while_loop`
error[E0425]: cannot find value `while_let` in this scope error[E0425]: cannot find value `while_let` in this scope
--> $DIR/label_misspelled.rs:11:9 --> $DIR/label_misspelled.rs:11:9
| |
LL | 'while_let: while let Some(_) = Some(()) {
| ---------- a label with a similar name exists
LL | while_let; LL | while_let;
| ^^^^^^^^^ | ^^^^^^^^^ not found in this scope
| |
| not found in this scope
| help: a label with a similar name exists: `'while_let`
error[E0425]: cannot find value `for_loop` in this scope error[E0425]: cannot find value `for_loop` in this scope
--> $DIR/label_misspelled.rs:15:9 --> $DIR/label_misspelled.rs:15:9
| |
LL | 'for_loop: for _ in 0..3 {
| --------- a label with a similar name exists
LL | for_loop; LL | for_loop;
| ^^^^^^^^ | ^^^^^^^^ not found in this scope
| |
| not found in this scope
| help: a label with a similar name exists: `'for_loop`
error[E0425]: cannot find value `LOOP` in this scope error[E0425]: cannot find value `LOOP` in this scope
--> $DIR/label_misspelled.rs:22:15 --> $DIR/label_misspelled.rs:22:15
| |
LL | 'LOOP: loop {
| ----- a label with a similar name exists
LL | break LOOP; LL | break LOOP;
| ^^^^ | ^^^^
| | | |
| not found in this scope | not found in this scope
| help: a label with a similar name exists: `'LOOP` | help: use the similarly named label: `'LOOP`
error[E0425]: cannot find value `while_loop` in this scope error[E0425]: cannot find value `while_loop` in this scope
--> $DIR/label_misspelled.rs:26:15 --> $DIR/label_misspelled.rs:26:15
| |
LL | 'while_loop: while true {
| ----------- a label with a similar name exists
LL | break while_loop; LL | break while_loop;
| ^^^^^^^^^^ | ^^^^^^^^^^
| | | |
| not found in this scope | not found in this scope
| help: a label with a similar name exists: `'while_loop` | help: use the similarly named label: `'while_loop`
error[E0425]: cannot find value `while_let` in this scope error[E0425]: cannot find value `while_let` in this scope
--> $DIR/label_misspelled.rs:31:15 --> $DIR/label_misspelled.rs:31:15
| |
LL | 'while_let: while let Some(_) = Some(()) {
| ---------- a label with a similar name exists
LL | break while_let; LL | break while_let;
| ^^^^^^^^^ | ^^^^^^^^^
| | | |
| not found in this scope | not found in this scope
| help: a label with a similar name exists: `'while_let` | help: use the similarly named label: `'while_let`
error[E0425]: cannot find value `for_loop` in this scope error[E0425]: cannot find value `for_loop` in this scope
--> $DIR/label_misspelled.rs:36:15 --> $DIR/label_misspelled.rs:36:15
| |
LL | 'for_loop: for _ in 0..3 {
| --------- a label with a similar name exists
LL | break for_loop; LL | break for_loop;
| ^^^^^^^^ | ^^^^^^^^
| | | |
| not found in this scope | not found in this scope
| help: a label with a similar name exists: `'for_loop` | help: use the similarly named label: `'for_loop`
warning: denote infinite loops with `loop { ... }` warning: denote infinite loops with `loop { ... }`
--> $DIR/label_misspelled.rs:6:5 --> $DIR/label_misspelled.rs:6:5

View file

@ -1,11 +1,13 @@
error[E0425]: cannot find value `LOOP` in this scope error[E0425]: cannot find value `LOOP` in this scope
--> $DIR/loop-break-value.rs:95:15 --> $DIR/loop-break-value.rs:95:15
| |
LL | 'LOOP: for _ in 0 .. 9 {
| ----- a label with a similar name exists
LL | break LOOP; LL | break LOOP;
| ^^^^ | ^^^^
| | | |
| not found in this scope | not found in this scope
| help: a label with a similar name exists: `'LOOP` | help: use the similarly named label: `'LOOP`
warning: denote infinite loops with `loop { ... }` warning: denote infinite loops with `loop { ... }`
--> $DIR/loop-break-value.rs:26:5 --> $DIR/loop-break-value.rs:26:5