|
1 | | -An associated const has been referenced in a pattern. |
| 1 | +An associated `const`, `const` parameter or `static` has been referenced |
| 2 | +in a pattern. |
2 | 3 |
|
3 | 4 | Erroneous code example: |
4 | 5 |
|
5 | 6 | ```compile_fail,E0158 |
6 | | -enum EFoo { A, B, C, D } |
| 7 | +enum Foo { |
| 8 | + One, |
| 9 | + Two |
| 10 | +} |
7 | 11 |
|
8 | | -trait Foo { |
9 | | - const X: EFoo; |
| 12 | +trait Bar { |
| 13 | + const X: Foo; |
10 | 14 | } |
11 | 15 |
|
12 | | -fn test<A: Foo>(arg: EFoo) { |
| 16 | +fn test<A: Bar>(arg: Foo) { |
13 | 17 | match arg { |
14 | | - A::X => { // error! |
15 | | - println!("A::X"); |
16 | | - } |
| 18 | + A::X => println!("A::X"), // error: E0158: associated consts cannot be |
| 19 | + // referenced in patterns |
| 20 | + Foo::Two => println!("Two") |
17 | 21 | } |
18 | 22 | } |
19 | 23 | ``` |
20 | 24 |
|
21 | | -`const` and `static` mean different things. A `const` is a compile-time |
22 | | -constant, an alias for a literal value. This property means you can match it |
23 | | -directly within a pattern. |
| 25 | +Associated `const`s cannot be referenced in patterns because it is impossible |
| 26 | +for the compiler to prove exhaustiveness (that some pattern will always match). |
| 27 | +Take the above example, because Rust does type checking in the *generic* |
| 28 | +method, not the *monomorphized* specific instance. So because `Bar` could have |
| 29 | +theoretically infinite implementations, there's no way to always be sure that |
| 30 | +`A::X` is `Foo::One`. So this code must be rejected. Even if code can be |
| 31 | +proven exhaustive by a programmer, the compiler cannot currently prove this. |
24 | 32 |
|
25 | | -The `static` keyword, on the other hand, guarantees a fixed location in memory. |
26 | | -This does not always mean that the value is constant. For example, a global |
27 | | -mutex can be declared `static` as well. |
| 33 | +The same holds true of `const` parameters and `static`s. |
28 | 34 |
|
29 | | -If you want to match against a `static`, consider using a guard instead: |
| 35 | +If you want to match against an associated `const`, `const` parameter or |
| 36 | +`static` consider using a guard instead: |
30 | 37 |
|
31 | 38 | ``` |
32 | | -static FORTY_TWO: i32 = 42; |
| 39 | +trait Trait { |
| 40 | + const X: char; |
| 41 | +} |
| 42 | +
|
| 43 | +static FOO: char = 'j'; |
33 | 44 |
|
34 | | -match Some(42) { |
35 | | - Some(x) if x == FORTY_TWO => {} |
36 | | - _ => {} |
| 45 | +fn test<A: Trait, const Y: char>(arg: char) { |
| 46 | + match arg { |
| 47 | + c if c == A::X => println!("A::X"), |
| 48 | + c if c == Y => println!("Y"), |
| 49 | + c if c == FOO => println!("FOO"), |
| 50 | + _ => () |
| 51 | + } |
37 | 52 | } |
38 | 53 | ``` |
0 commit comments