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: Erroneous code example:
```compile_fail,E0158 ```compile_fail,E0158
enum EFoo { A, B, C, D } enum Foo {
One,
trait Foo { Two
const X: EFoo;
} }
fn test<A: Foo>(arg: EFoo) { trait Bar {
const X: Foo;
}
fn test<A: Bar>(arg: Foo) {
match arg { match arg {
A::X => { // error! A::X => println!("A::X"), // error: E0158: associated consts cannot be
println!("A::X"); // referenced in patterns
} Foo::Two => println!("Two")
} }
} }
``` ```
`const` and `static` mean different things. A `const` is a compile-time Associated `const`s cannot be referenced in patterns because it is impossible
constant, an alias for a literal value. This property means you can match it for the compiler to prove exhaustiveness (that some pattern will always match).
directly within a pattern. 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. The same holds true of `const` parameters and `static`s.
This does not always mean that the value is constant. For example, a global
mutex can be declared `static` as well.
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) { static FOO: char = 'j';
Some(x) if x == FORTY_TWO => {}
_ => {} 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"),
_ => ()
}
} }
``` ```