Skip to content

Commit 24ff1e0

Browse files
committed
Rollup merge of rust-lang#33493 - Manishearth:more-diag, r=GuillaumeGomez
Librustc_resolve diagnostics fixes r? @GuillaumeGomez
2 parents 6249772 + a795419 commit 24ff1e0

File tree

2 files changed

+93
-21
lines changed

2 files changed

+93
-21
lines changed

src/librustc_resolve/diagnostics.rs

+85-4
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,90 @@ impl Bar {
497497
```
498498
"##,
499499

500+
E0408: r##"
501+
An "or" pattern was used where the variable bindings are not consistently bound
502+
across patterns.
503+
504+
Example of erroneous code:
505+
506+
```compile_fail
507+
match x {
508+
Some(y) | None => { /* use y */ } // error: variable `y` from pattern #1 is
509+
// not bound in pattern #2
510+
_ => ()
511+
}
512+
```
513+
514+
Here, `y` is bound to the contents of the `Some` and can be used within the
515+
block corresponding to the match arm. However, in case `x` is `None`, we have
516+
not specified what `y` is, and the block will use a nonexistent variable.
517+
518+
To fix this error, either split into multiple match arms:
519+
520+
```
521+
let x = Some(1);
522+
match x {
523+
Some(y) => { /* use y */ }
524+
None => { /* ... */ }
525+
}
526+
```
527+
528+
or, bind the variable to a field of the same type in all sub-patterns of the
529+
or pattern:
530+
531+
```
532+
let x = (0, 2);
533+
match x {
534+
(0, y) | (y, 0) => { /* use y */}
535+
}
536+
```
537+
538+
In this example, if `x` matches the pattern `(0, _)`, the second field is set
539+
to `y`. If it matches `(_, 0)`, the first field is set to `y`; so in all
540+
cases `y` is set to some value.
541+
"##,
542+
543+
E0409: r##"
544+
An "or" pattern was used where the variable bindings are not consistently bound
545+
across patterns.
546+
547+
Example of erroneous code:
548+
549+
```compile_fail
550+
let x = (0, 2);
551+
match x {
552+
(0, ref y) | (y, 0) => { /* use y */} // error: variable `y` is bound with
553+
// different mode in pattern #2
554+
// than in pattern #1
555+
_ => ()
556+
}
557+
```
558+
559+
Here, `y` is bound by-value in one case and by-reference in the other.
560+
561+
To fix this error, just use the same mode in both cases.
562+
Generally using `ref` or `ref mut` where not already used will fix this:
563+
564+
```
565+
let x = (0, 2);
566+
match x {
567+
(0, ref y) | (ref y, 0) => { /* use y */}
568+
_ => ()
569+
}
570+
```
571+
572+
Alternatively, split the pattern:
573+
574+
```
575+
let x = (0, 2);
576+
match x {
577+
(y, 0) => { /* use y */ }
578+
(0, ref y) => { /* use y */}
579+
_ => ()
580+
}
581+
```
582+
"##,
583+
500584
E0411: r##"
501585
The `Self` keyword was used outside an impl or a trait. Erroneous code example:
502586
@@ -1145,10 +1229,7 @@ register_diagnostics! {
11451229
// E0258,
11461230
E0402, // cannot use an outer type parameter in this context
11471231
E0406, // undeclared associated type
1148-
E0408, // variable from pattern #1 is not bound in pattern #
1149-
E0409, // variable is bound with different mode in pattern # than in
1150-
// pattern #1
1151-
E0410, // variable from pattern is not bound in pattern 1
1232+
// E0410, merged into 408
11521233
E0418, // is not an enum variant, struct or const
11531234
E0420, // is not an associated const
11541235
E0421, // unresolved associated const

src/librustc_resolve/lib.rs

+8-17
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,10 @@ enum ResolutionError<'a> {
126126
TypeNotMemberOfTrait(Name, &'a str),
127127
/// error E0438: const is not a member of trait
128128
ConstNotMemberOfTrait(Name, &'a str),
129-
/// error E0408: variable `{}` from pattern #1 is not bound in pattern
130-
VariableNotBoundInPattern(Name, usize),
129+
/// error E0408: variable `{}` from pattern #{} is not bound in pattern #{}
130+
VariableNotBoundInPattern(Name, usize, usize),
131131
/// error E0409: variable is bound with different mode in pattern #{} than in pattern #1
132132
VariableBoundWithDifferentMode(Name, usize),
133-
/// error E0410: variable from pattern is not bound in pattern #1
134-
VariableNotBoundInParentPattern(Name, usize),
135133
/// error E0411: use of `Self` outside of an impl or trait
136134
SelfUsedOutsideImplOrTrait,
137135
/// error E0412: use of undeclared
@@ -272,13 +270,14 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
272270
const_,
273271
trait_)
274272
}
275-
ResolutionError::VariableNotBoundInPattern(variable_name, pattern_number) => {
273+
ResolutionError::VariableNotBoundInPattern(variable_name, from, to) => {
276274
struct_span_err!(resolver.session,
277275
span,
278276
E0408,
279-
"variable `{}` from pattern #1 is not bound in pattern #{}",
277+
"variable `{}` from pattern #{} is not bound in pattern #{}",
280278
variable_name,
281-
pattern_number)
279+
from,
280+
to)
282281
}
283282
ResolutionError::VariableBoundWithDifferentMode(variable_name, pattern_number) => {
284283
struct_span_err!(resolver.session,
@@ -289,14 +288,6 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
289288
variable_name,
290289
pattern_number)
291290
}
292-
ResolutionError::VariableNotBoundInParentPattern(variable_name, pattern_number) => {
293-
struct_span_err!(resolver.session,
294-
span,
295-
E0410,
296-
"variable `{}` from pattern #{} is not bound in pattern #1",
297-
variable_name,
298-
pattern_number)
299-
}
300291
ResolutionError::SelfUsedOutsideImplOrTrait => {
301292
struct_span_err!(resolver.session,
302293
span,
@@ -2038,7 +2029,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
20382029
None => {
20392030
resolve_error(self,
20402031
p.span,
2041-
ResolutionError::VariableNotBoundInPattern(key, i + 1));
2032+
ResolutionError::VariableNotBoundInPattern(key, 1, i + 1));
20422033
}
20432034
Some(binding_i) => {
20442035
if binding_0.binding_mode != binding_i.binding_mode {
@@ -2055,7 +2046,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
20552046
if !map_0.contains_key(&key) {
20562047
resolve_error(self,
20572048
binding.span,
2058-
ResolutionError::VariableNotBoundInParentPattern(key, i + 1));
2049+
ResolutionError::VariableNotBoundInPattern(key, i + 1, 1));
20592050
}
20602051
}
20612052
}

0 commit comments

Comments
 (0)