]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_resolve/diagnostics.rs
add explanation for E0429 (`self` use declaration must use brace syntax)
[rust.git] / src / librustc_resolve / diagnostics.rs
index 0a8fce49ebbaf2f2b2edac7e95dea1952fc37c72..177a85709e445ca6aa902a36a0e966d29c67a5d8 100644 (file)
@@ -497,6 +497,91 @@ fn b() {}
 ```
 "##,
 
+E0408: r##"
+An "or" pattern was used where the variable bindings are not consistently bound
+across patterns.
+
+Example of erroneous code:
+
+```compile_fail
+match x {
+    Some(y) | None => { /* use y */ } // error: variable `y` from pattern #1 is
+                                      //        not bound in pattern #2
+    _ => ()
+}
+```
+
+Here, `y` is bound to the contents of the `Some` and can be used within the
+block corresponding to the match arm. However, in case `x` is `None`, we have
+not specified what `y` is, and the block will use a nonexistent variable.
+
+To fix this error, either split into multiple match arms:
+
+```
+let x = Some(1);
+match x {
+    Some(y) => { /* use y */ }
+    None => { /* ... */ }
+}
+```
+
+or, bind the variable to a field of the same type in all sub-patterns of the
+or pattern:
+
+```
+let x = (0, 2);
+match x {
+    (0, y) | (y, 0) => { /* use y */}
+    _ => {}
+}
+```
+
+In this example, if `x` matches the pattern `(0, _)`, the second field is set
+to `y`. If it matches `(_, 0)`, the first field is set to `y`; so in all
+cases `y` is set to some value.
+"##,
+
+E0409: r##"
+An "or" pattern was used where the variable bindings are not consistently bound
+across patterns.
+
+Example of erroneous code:
+
+```compile_fail
+let x = (0, 2);
+match x {
+    (0, ref y) | (y, 0) => { /* use y */} // error: variable `y` is bound with
+                                          //        different mode in pattern #2
+                                          //        than in pattern #1
+    _ => ()
+}
+```
+
+Here, `y` is bound by-value in one case and by-reference in the other.
+
+To fix this error, just use the same mode in both cases.
+Generally using `ref` or `ref mut` where not already used will fix this:
+
+```ignore
+let x = (0, 2);
+match x {
+    (0, ref y) | (ref y, 0) => { /* use y */}
+    _ => ()
+}
+```
+
+Alternatively, split the pattern:
+
+```
+let x = (0, 2);
+match x {
+    (y, 0) => { /* use y */ }
+    (0, ref y) => { /* use y */}
+    _ => ()
+}
+```
+"##,
+
 E0411: r##"
 The `Self` keyword was used outside an impl or a trait. Erroneous code example:
 
@@ -623,6 +708,69 @@ fn foo<T>(x: T) {} // ok!
 The goal here is to avoid a conflict of names.
 "##,
 
+E0414: r##"
+A variable binding in an irrefutable pattern is shadowing the name of a
+constant. Example of erroneous code:
+
+```compile_fail
+const FOO: u8 = 7;
+
+let FOO = 5; // error: variable bindings cannot shadow constants
+
+// or
+
+fn bar(FOO: u8) { // error: variable bindings cannot shadow constants
+
+}
+
+// or
+
+for FOO in bar {
+
+}
+```
+
+Introducing a new variable in Rust is done through a pattern. Thus you can have
+`let` bindings like `let (a, b) = ...`. However, patterns also allow constants
+in them, e.g. if you want to match over a constant:
+
+```ignore
+const FOO: u8 = 1;
+
+match (x,y) {
+ (3, 4) => { .. }, // it is (3,4)
+ (FOO, 1) => { .. }, // it is (1,1)
+ (foo, 1) => { .. }, // it is (anything, 1)
+                     // call the value in the first slot "foo"
+ _ => { .. } // it is anything
+}
+```
+
+Here, the second arm matches the value of `x` against the constant `FOO`,
+whereas the third arm will accept any value of `x` and call it `foo`.
+
+This works for `match`, however in cases where an irrefutable pattern is
+required, constants can't be used. An irrefutable pattern is one which always
+matches, whose purpose is only to bind variable names to values. These are
+required by let, for, and function argument patterns.
+
+Refutable patterns in such a situation do not make sense, for example:
+
+```ignore
+let Some(x) = foo; // what if foo is None, instead?
+
+let (1, x) = foo; // what if foo.0 is not 1?
+
+let (SOME_CONST, x) = foo; // what if foo.0 is not SOME_CONST?
+
+let SOME_CONST = foo; // what if foo is not SOME_CONST?
+```
+
+Thus, an irrefutable variable binding can't contain a constant.
+
+To fix this error, just give the marked variable a different name.
+"##,
+
 E0415: r##"
 More than one function parameter have the same name. Example of erroneous code:
 
@@ -881,6 +1029,32 @@ mod something_that_does_exist {
 ```
 "##,
 
+E0429: r##"
+To import a namespace itself in addition to some of its members, the `self`
+keyword may appear in a brace-enclosed list as the last segment in a `use`
+declaration. However, `self` cannot be used alone, without the brace
+syntax.
+
+Example of erroneous code:
+
+```compile_fail
+use std::fmt::self; // error: `self` imports are only allowed within a { } list
+```
+
+If you only want to import the namespace, do so directly:
+
+```
+use std::fmt;
+```
+
+If you also want to import members in the same statement, you may use the brace
+syntax:
+
+```
+use std::fmt::{self, Debug};
+```
+"##,
+
 E0430: r##"
 The `self` import appears more than once in the list. Erroneous code example:
 
@@ -916,11 +1090,14 @@ mod something_that_does_exist {
 use something::Foo; // error: unresolved import `something::Foo`.
 ```
 
-Please verify you didn't misspell the import name or the import does exist
-in the module from where you tried to import it. Example:
+Paths in `use` statements are relative to the crate root. To import items
+relative to the current and parent modules, use the `self::` and `super::`
+prefixes, respectively. Also verify that you didn't misspell the import
+name and that the import exists in the module from where you tried to
+import it. Example:
 
 ```ignore
-use something::Foo; // ok!
+use self::something::Foo; // ok!
 
 mod something {
     pub struct Foo;
@@ -928,7 +1105,7 @@ mod something {
 ```
 
 Or, if you tried to use a module from an external crate, you may have missed
-the `extern crate` declaration:
+the `extern crate` declaration (which is usually placed in the crate root):
 
 ```ignore
 extern crate homura; // Required to use the `homura` crate
@@ -1079,14 +1256,9 @@ impl Foo for i32 {}
 //  E0258,
     E0402, // cannot use an outer type parameter in this context
     E0406, // undeclared associated type
-    E0408, // variable from pattern #1 is not bound in pattern #
-    E0409, // variable is bound with different mode in pattern # than in
-           // pattern #1
-    E0410, // variable from pattern is not bound in pattern 1
-    E0414, // only irrefutable patterns allowed here
+//  E0410, merged into 408
     E0418, // is not an enum variant, struct or const
     E0420, // is not an associated const
     E0421, // unresolved associated const
     E0427, // cannot use `ref` binding mode with ...
-    E0429, // `self` imports are only allowed within a { } list
 }