Skip to content

Commit 9f302b6

Browse files
committed
Add long diagnostics for E0414
1 parent 5f9e304 commit 9f302b6

File tree

1 file changed

+63
-1
lines changed

1 file changed

+63
-1
lines changed

src/librustc_resolve/diagnostics.rs

+63-1
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,69 @@ let Foo = 12i32; // ok!
623623
The goal here is to avoid a conflict of names.
624624
"##,
625625

626+
E0414: r##"
627+
A variable binding in an irrefutable pattern is shadowing the name of a
628+
constant. Example of erroneous code:
629+
630+
```compile_fail
631+
const FOO: u8 = 7;
632+
633+
let FOO = 5; // error: variable bindings cannot shadow constants
634+
635+
// or
636+
637+
fn bar(FOO: u8) { // error: variable bindings cannot shadow constants
638+
639+
}
640+
641+
// or
642+
643+
for FOO in bar {
644+
645+
}
646+
```
647+
648+
Introducing a new variable in Rust is done through a pattern. Thus you can have
649+
`let` bindings like `let (a, b) = ...`. However, patterns also allow constants
650+
in them, e.g. if you want to match over a constant:
651+
652+
```ignore
653+
const FOO: u8 = 1;
654+
655+
match (x,y) {
656+
(3, 4) => { .. }, // it is (3,4)
657+
(FOO, 1) => { .. }, // it is (1,1)
658+
(foo, 1) => { .. }, // it is (anything, 1)
659+
// call the value in the first slot "foo"
660+
_ => { .. } // it is anything
661+
}
662+
```
663+
664+
Here, the second arm matches the value of `x` against the constant `FOO`,
665+
whereas the third arm will accept any value of `x` and call it `foo`.
666+
667+
This works for `match`, however in cases where an irrefutable pattern is
668+
required, constants can't be used. An irrefutable pattern is one which always
669+
matches, whose purpose is only to bind variable names to values. These are
670+
required by let, for, and function argument patterns.
671+
672+
Refutable patterns in such a situation do not make sense, for example:
673+
674+
```ignore
675+
let Some(x) = foo; // what if foo is None, instead?
676+
677+
let (1, x) = foo; // what if foo.0 is not 1?
678+
679+
let (SOME_CONST, x) = foo; // what if foo.0 is not SOME_CONST?
680+
681+
let SOME_CONST = foo; // what if foo is not SOME_CONST?
682+
```
683+
684+
Thus, an irrefutable variable binding can't contain a constant.
685+
686+
To fix this error, just give the marked variable a different name.
687+
"##,
688+
626689
E0415: r##"
627690
More than one function parameter have the same name. Example of erroneous code:
628691
@@ -1086,7 +1149,6 @@ register_diagnostics! {
10861149
E0409, // variable is bound with different mode in pattern # than in
10871150
// pattern #1
10881151
E0410, // variable from pattern is not bound in pattern 1
1089-
E0414, // only irrefutable patterns allowed here
10901152
E0418, // is not an enum variant, struct or const
10911153
E0420, // is not an associated const
10921154
E0421, // unresolved associated const

0 commit comments

Comments
 (0)