1
Fork 0

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.
This commit is contained in:
Matthias Krüger 2022-12-16 14:02:18 +01:00 committed by GitHub
commit 3b9aea967f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,38 +1,53 @@
An associated const has been referenced in a pattern.
An associated `const`, `const` parameter or `static` has been referenced
in a pattern.
Erroneous code example:
```compile_fail,E0158
enum EFoo { A, B, C, D }
trait Foo {
const X: EFoo;
enum Foo {
One,
Two
}
fn test<A: Foo>(arg: EFoo) {
trait Bar {
const X: Foo;
}
fn test<A: Bar>(arg: Foo) {
match arg {
A::X => { // error!
println!("A::X");
}
A::X => println!("A::X"), // error: E0158: associated consts cannot be
// referenced in patterns
Foo::Two => println!("Two")
}
}
```
`const` and `static` mean different things. A `const` is a compile-time
constant, an alias for a literal value. This property means you can match it
directly within a pattern.
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 `static` keyword, on the other hand, guarantees a fixed location in memory.
This does not always mean that the value is constant. For example, a global
mutex can be declared `static` as well.
The same holds true of `const` parameters and `static`s.
If you want to match against a `static`, consider using a guard instead:
If you want to match against an associated `const`, `const` parameter or
`static` consider using a guard instead:
```
static FORTY_TWO: i32 = 42;
trait Trait {
const X: char;
}
match Some(42) {
Some(x) if x == FORTY_TWO => {}
_ => {}
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"),
_ => ()
}
}
```