Skip to content

Commit 3b9aea9

Browse files
authored
Rollup merge of #105744 - Ezrashaw:e0158-clarity, r=GuillaumeGomez
Rewrite `E0158` error-code docs for clarity Fixes #105585. The `E0158` error-code docs are unclear. It doesn't explain all three different variants of the error and doesn't explain *why* the error occurs. This PR cleans it up a bit and brings it properly into line with [RFC1567](https://rust-lang.github.io/rfcs/1567-long-error-codes-explanation-normalization.html). I'm a first time Rust contributor so I've probably not got it quite right. I also haven't run the whole build process because I assume that my minor docs changes shouldn't break everything.
2 parents 22797ef + fded03e commit 3b9aea9

File tree

1 file changed

+34
-19
lines changed
  • compiler/rustc_error_codes/src/error_codes

1 file changed

+34
-19
lines changed
Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,53 @@
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.
23

34
Erroneous code example:
45

56
```compile_fail,E0158
6-
enum EFoo { A, B, C, D }
7+
enum Foo {
8+
One,
9+
Two
10+
}
711
8-
trait Foo {
9-
const X: EFoo;
12+
trait Bar {
13+
const X: Foo;
1014
}
1115
12-
fn test<A: Foo>(arg: EFoo) {
16+
fn test<A: Bar>(arg: Foo) {
1317
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")
1721
}
1822
}
1923
```
2024

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.
2432

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.
2834

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:
3037

3138
```
32-
static FORTY_TWO: i32 = 42;
39+
trait Trait {
40+
const X: char;
41+
}
42+
43+
static FOO: char = 'j';
3344
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+
}
3752
}
3853
```

0 commit comments

Comments
 (0)