-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Suggest using a qualified path in patterns with inconsistent bindings
A program like the following one: ```rust enum E { A, B, C } fn f(x: E) -> bool { match x { A | B => false, C => true } } ``` is rejected by the compiler due to `E` variant paths not being in scope. In this case `A`, `B` are resolved as pattern bindings and consequently the pattern is considered invalid as the inner or-patterns do not bind to the same set of identifiers. This is expected but the compiler errors that follow could be surprising or confusing to some users. This commit adds a help note explaining that if the user desired to match against variants or consts, they should use a qualified path. The note is restricted to cases where the identifier starts with an upper-case sequence so as to reduce the false negatives. Since this happens during resolution, there's no clean way to check what the patterns match against. The syntactic criterium, however, is in line with the convention that's assumed by the `non-camel-case-types` lint.
- Loading branch information
1 parent
2628f57
commit 7e0d1db
Showing
3 changed files
with
156 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,36 @@ | ||
#![allow(non_camel_case_types)] | ||
|
||
enum E { A, B, c } | ||
|
||
mod m { | ||
const CONST1: usize = 10; | ||
const Const2: usize = 20; | ||
} | ||
|
||
fn main() { | ||
let y = 1; | ||
match y { | ||
a | b => {} //~ ERROR variable `a` is not bound in all patterns | ||
//~^ ERROR variable `b` is not bound in all patterns | ||
//~| ERROR variable `b` is not bound in all patterns | ||
} | ||
|
||
let x = (E::A, E::B); | ||
match x { | ||
(A, B) | (ref B, c) | (c, A) => () | ||
//~^ ERROR variable `A` is not bound in all patterns | ||
//~| ERROR variable `B` is not bound in all patterns | ||
//~| ERROR variable `B` is bound in inconsistent ways | ||
//~| ERROR mismatched types | ||
//~| ERROR variable `c` is not bound in all patterns | ||
//~| HELP consider making the path in the pattern qualified: `?::A` | ||
} | ||
|
||
let z = (10, 20); | ||
match z { | ||
(CONST1, _) | (_, Const2) => () | ||
//~^ ERROR variable `CONST1` is not bound in all patterns | ||
//~| HELP consider making the path in the pattern qualified: `?::CONST1` | ||
//~| ERROR variable `Const2` is not bound in all patterns | ||
//~| HELP consider making the path in the pattern qualified: `?::Const2` | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,98 @@ | ||
error[E0408]: variable `a` is not bound in all patterns | ||
--> $DIR/resolve-inconsistent-names.rs:4:12 | ||
--> $DIR/resolve-inconsistent-names.rs:13:12 | ||
| | ||
LL | a | b => {} | ||
| - ^ pattern doesn't bind `a` | ||
| | | ||
| variable not in all patterns | ||
|
||
error[E0408]: variable `b` is not bound in all patterns | ||
--> $DIR/resolve-inconsistent-names.rs:4:8 | ||
--> $DIR/resolve-inconsistent-names.rs:13:8 | ||
| | ||
LL | a | b => {} | ||
| ^ - variable not in all patterns | ||
| | | ||
| pattern doesn't bind `b` | ||
|
||
error: aborting due to 2 previous errors | ||
error[E0408]: variable `A` is not bound in all patterns | ||
--> $DIR/resolve-inconsistent-names.rs:19:18 | ||
| | ||
LL | (A, B) | (ref B, c) | (c, A) => () | ||
| - ^^^^^^^^^^ - variable not in all patterns | ||
| | | | ||
| | pattern doesn't bind `A` | ||
| variable not in all patterns | ||
| | ||
help: if you meant to match on a variant or a const, consider making the path in the pattern qualified: `?::A` | ||
--> $DIR/resolve-inconsistent-names.rs:19:10 | ||
| | ||
LL | (A, B) | (ref B, c) | (c, A) => () | ||
| ^ | ||
|
||
error[E0408]: variable `B` is not bound in all patterns | ||
--> $DIR/resolve-inconsistent-names.rs:19:31 | ||
| | ||
LL | (A, B) | (ref B, c) | (c, A) => () | ||
| - - ^^^^^^ pattern doesn't bind `B` | ||
| | | | ||
| | variable not in all patterns | ||
| variable not in all patterns | ||
|
||
error[E0408]: variable `c` is not bound in all patterns | ||
--> $DIR/resolve-inconsistent-names.rs:19:9 | ||
| | ||
LL | (A, B) | (ref B, c) | (c, A) => () | ||
| ^^^^^^ - - variable not in all patterns | ||
| | | | ||
| | variable not in all patterns | ||
| pattern doesn't bind `c` | ||
|
||
error[E0409]: variable `B` is bound in inconsistent ways within the same match arm | ||
--> $DIR/resolve-inconsistent-names.rs:19:23 | ||
| | ||
LL | (A, B) | (ref B, c) | (c, A) => () | ||
| - ^ bound in different ways | ||
| | | ||
| first binding | ||
|
||
error[E0408]: variable `CONST1` is not bound in all patterns | ||
--> $DIR/resolve-inconsistent-names.rs:30:23 | ||
| | ||
LL | (CONST1, _) | (_, Const2) => () | ||
| ------ ^^^^^^^^^^^ pattern doesn't bind `CONST1` | ||
| | | ||
| variable not in all patterns | ||
| | ||
help: if you meant to match on a variant or a const, consider making the path in the pattern qualified: `?::CONST1` | ||
--> $DIR/resolve-inconsistent-names.rs:30:10 | ||
| | ||
LL | (CONST1, _) | (_, Const2) => () | ||
| ^^^^^^ | ||
|
||
error[E0408]: variable `Const2` is not bound in all patterns | ||
--> $DIR/resolve-inconsistent-names.rs:30:9 | ||
| | ||
LL | (CONST1, _) | (_, Const2) => () | ||
| ^^^^^^^^^^^ ------ variable not in all patterns | ||
| | | ||
| pattern doesn't bind `Const2` | ||
| | ||
help: if you meant to match on a variant or a const, consider making the path in the pattern qualified: `?::Const2` | ||
--> $DIR/resolve-inconsistent-names.rs:30:27 | ||
| | ||
LL | (CONST1, _) | (_, Const2) => () | ||
| ^^^^^^ | ||
|
||
error[E0308]: mismatched types | ||
--> $DIR/resolve-inconsistent-names.rs:19:19 | ||
| | ||
LL | (A, B) | (ref B, c) | (c, A) => () | ||
| ^^^^^ expected enum `E`, found &E | ||
| | ||
= note: expected type `E` | ||
found type `&E` | ||
|
||
error: aborting due to 9 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0408`. | ||
Some errors have detailed explanations: E0308, E0408, E0409. | ||
For more information about an error, try `rustc --explain E0308`. |