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);
}
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) => {
self.visit_expr(scrutinee);
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_ident, _) in &label_rib.bindings {
if format!("'{}", ident) == label_ident.to_string() {
let msg = "a label with a similar name exists";
// FIXME: consider only emitting this suggestion if a label would be valid here
// which is pretty much only the case for `break` expressions.
err.span_suggestion(
span,
&msg,
label_ident.name.to_string(),
Applicability::MaybeIncorrect,
);
err.span_label(label_ident.span, "a label with a similar name exists");
if let PathSource::Expr(Some(Expr {
kind: ExprKind::Break(None, Some(_)),
..
})) = source
{
err.span_suggestion(
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
--> $DIR/label_misspelled.rs:3:9
|
LL | 'LOOP: loop {
| ----- a label with a similar name exists
LL | LOOP;
| ^^^^
| |
| not found in this scope
| help: a label with a similar name exists: `'LOOP`
| ^^^^ not found in this scope
error[E0425]: cannot find value `while_loop` in this scope
--> $DIR/label_misspelled.rs:7:9
|
LL | 'while_loop: while true {
| ----------- a label with a similar name exists
LL | while_loop;
| ^^^^^^^^^^
| |
| not found in this scope
| help: a label with a similar name exists: `'while_loop`
| ^^^^^^^^^^ not found in this scope
error[E0425]: cannot find value `while_let` in this scope
--> $DIR/label_misspelled.rs:11:9
|
LL | 'while_let: while let Some(_) = Some(()) {
| ---------- a label with a similar name exists
LL | while_let;
| ^^^^^^^^^
| |
| not found in this scope
| help: a label with a similar name exists: `'while_let`
| ^^^^^^^^^ not found in this scope
error[E0425]: cannot find value `for_loop` in this scope
--> $DIR/label_misspelled.rs:15:9
|
LL | 'for_loop: for _ in 0..3 {
| --------- a label with a similar name exists
LL | for_loop;
| ^^^^^^^^
| |
| not found in this scope
| help: a label with a similar name exists: `'for_loop`
| ^^^^^^^^ not found in this scope
error[E0425]: cannot find value `LOOP` in this scope
--> $DIR/label_misspelled.rs:22:15
|
LL | 'LOOP: loop {
| ----- a label with a similar name exists
LL | break LOOP;
| ^^^^
| |
| 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
--> $DIR/label_misspelled.rs:26:15
|
LL | 'while_loop: while true {
| ----------- a label with a similar name exists
LL | break while_loop;
| ^^^^^^^^^^
| |
| 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
--> $DIR/label_misspelled.rs:31:15
|
LL | 'while_let: while let Some(_) = Some(()) {
| ---------- a label with a similar name exists
LL | break while_let;
| ^^^^^^^^^
| |
| 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
--> $DIR/label_misspelled.rs:36:15
|
LL | 'for_loop: for _ in 0..3 {
| --------- a label with a similar name exists
LL | break for_loop;
| ^^^^^^^^
| |
| 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 { ... }`
--> $DIR/label_misspelled.rs:6:5

View File

@ -1,11 +1,13 @@
error[E0425]: cannot find value `LOOP` in this scope
--> $DIR/loop-break-value.rs:95:15
|
LL | 'LOOP: for _ in 0 .. 9 {
| ----- a label with a similar name exists
LL | break LOOP;
| ^^^^
| |
| 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 { ... }`
--> $DIR/loop-break-value.rs:26:5