summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_error_codes/src/error_codes/E0158.md
blob: 03b93d925c19a3f5c0eab3202af14735ab04cfdf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
An associated `const`, `const` parameter or `static` has been referenced
in a pattern.

Erroneous code example:

```compile_fail,E0158
enum Foo {
    One,
    Two
}

trait Bar {
    const X: Foo;
}

fn test<A: Bar>(arg: Foo) {
    match arg {
        A::X => println!("A::X"), // error: E0158: associated consts cannot be
                                  //        referenced in patterns
        Foo::Two => println!("Two")
    }
}
```

Associated `const`s cannot be referenced in patterns because it is impossible
for the compiler to prove exhaustiveness (that some pattern will always match).
Take the above example, because Rust does type checking in the *generic*
method, not the *monomorphized* specific instance. So because `Bar` could have
theoretically infinite implementations, there's no way to always be sure that
`A::X` is `Foo::One`. So this code must be rejected. Even if code can be
proven exhaustive by a programmer, the compiler cannot currently prove this.

The same holds true of `const` parameters and `static`s.

If you want to match against an associated `const`, `const` parameter or
`static` consider using a guard instead:

```
trait Trait {
    const X: char;
}

static FOO: char = 'j';

fn test<A: Trait, const Y: char>(arg: char) {
    match arg {
        c if c == A::X => println!("A::X"),
        c if c == Y => println!("Y"),
        c if c == FOO => println!("FOO"),
        _ => ()
    }
}
```