|
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