about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEzra Shaw <ezrasure@outlook.com>2022-12-16 08:36:40 +1300
committerEzra Shaw <ezrasure@outlook.com>2022-12-16 08:36:40 +1300
commitfded03ee2d421359e49a69b6afa7d7f65ef9f597 (patch)
tree96505e81b34959343a04bb993bad0ee8a4d80a7e
parenta8847df167c5851caf8f465354fc3d73b7e9338c (diff)
downloadrust-fded03ee2d421359e49a69b6afa7d7f65ef9f597.tar.gz
rust-fded03ee2d421359e49a69b6afa7d7f65ef9f597.zip
docs: rewrite E0158 error-code docs for clarity
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0158.md53
1 files changed, 34 insertions, 19 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0158.md b/compiler/rustc_error_codes/src/error_codes/E0158.md
index 0a9ef9c3938..03b93d925c1 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0158.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0158.md
@@ -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 }
+enum Foo {
+    One,
+    Two
+}
 
-trait Foo {
-    const X: EFoo;
+trait Bar {
+    const X: Foo;
 }
 
-fn test<A: Foo>(arg: EFoo) {
+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;
+}
+
+static FOO: char = 'j';
 
-match Some(42) {
-    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"),
+        _ => ()
+    }
 }
 ```