Merge unreachable subpatterns correctly
This commit is contained in:
parent
2d71a0b9b9
commit
6319d737e0
@ -788,13 +788,32 @@ impl<'tcx> Usefulness<'tcx> {
|
|||||||
/// When trying several branches and each returns a `Usefulness`, we need to combine the
|
/// When trying several branches and each returns a `Usefulness`, we need to combine the
|
||||||
/// results together.
|
/// results together.
|
||||||
fn merge_split_constructors(usefulnesses: impl Iterator<Item = Self>) -> Self {
|
fn merge_split_constructors(usefulnesses: impl Iterator<Item = Self>) -> Self {
|
||||||
|
// If we have detected some unreachable sub-branches, we only want to keep them when they
|
||||||
|
// were unreachable in _all_ branches. So we take a big intersection.
|
||||||
|
|
||||||
|
// Is `None` when no branch was useful. Will often be `Some(Spanset::new())` because the
|
||||||
|
// sets are only non-empty in the diagnostic path.
|
||||||
|
let mut unreachables: Option<SpanSet> = None;
|
||||||
// Witnesses of usefulness, if any.
|
// Witnesses of usefulness, if any.
|
||||||
let mut witnesses = Vec::new();
|
let mut witnesses = Vec::new();
|
||||||
|
|
||||||
for u in usefulnesses {
|
for u in usefulnesses {
|
||||||
match u {
|
match u {
|
||||||
Useful(..) => {
|
Useful(spans) if spans.is_empty() => {
|
||||||
return u;
|
// Once we reach the empty set, more intersections won't change the result.
|
||||||
|
return Useful(SpanSet::new());
|
||||||
|
}
|
||||||
|
Useful(spans) => {
|
||||||
|
if let Some(unreachables) = &mut unreachables {
|
||||||
|
if !unreachables.is_empty() {
|
||||||
|
unreachables.intersection_mut(&spans);
|
||||||
|
}
|
||||||
|
if unreachables.is_empty() {
|
||||||
|
return Useful(SpanSet::new());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unreachables = Some(spans);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
NotUseful => {}
|
NotUseful => {}
|
||||||
UsefulWithWitness(wits) => {
|
UsefulWithWitness(wits) => {
|
||||||
@ -803,7 +822,13 @@ impl<'tcx> Usefulness<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !witnesses.is_empty() { UsefulWithWitness(witnesses) } else { NotUseful }
|
if !witnesses.is_empty() {
|
||||||
|
UsefulWithWitness(witnesses)
|
||||||
|
} else if let Some(unreachables) = unreachables {
|
||||||
|
Useful(unreachables)
|
||||||
|
} else {
|
||||||
|
NotUseful
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_constructor<'p>(
|
fn apply_constructor<'p>(
|
||||||
|
@ -64,11 +64,9 @@ fn main() {
|
|||||||
| 2, ..] => {}
|
| 2, ..] => {}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
// FIXME: incorrect
|
|
||||||
match &[][..] {
|
match &[][..] {
|
||||||
[true] => {}
|
[true] => {}
|
||||||
[true //~ ERROR unreachable
|
[true | false, ..] => {}
|
||||||
| false, ..] => {}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
match &[][..] {
|
match &[][..] {
|
||||||
|
@ -95,46 +95,40 @@ LL | [1
|
|||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unreachable pattern
|
error: unreachable pattern
|
||||||
--> $DIR/exhaustiveness-unreachable-pattern.rs:70:10
|
--> $DIR/exhaustiveness-unreachable-pattern.rs:75:10
|
||||||
|
|
|
|
||||||
LL | [true
|
LL | [true
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: unreachable pattern
|
error: unreachable pattern
|
||||||
--> $DIR/exhaustiveness-unreachable-pattern.rs:77:10
|
--> $DIR/exhaustiveness-unreachable-pattern.rs:82:36
|
||||||
|
|
|
||||||
LL | [true
|
|
||||||
| ^^^^
|
|
||||||
|
|
||||||
error: unreachable pattern
|
|
||||||
--> $DIR/exhaustiveness-unreachable-pattern.rs:84:36
|
|
||||||
|
|
|
|
||||||
LL | (true | false, None | Some(true
|
LL | (true | false, None | Some(true
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: unreachable pattern
|
error: unreachable pattern
|
||||||
--> $DIR/exhaustiveness-unreachable-pattern.rs:100:14
|
--> $DIR/exhaustiveness-unreachable-pattern.rs:98:14
|
||||||
|
|
|
|
||||||
LL | Some(0
|
LL | Some(0
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unreachable pattern
|
error: unreachable pattern
|
||||||
--> $DIR/exhaustiveness-unreachable-pattern.rs:119:19
|
--> $DIR/exhaustiveness-unreachable-pattern.rs:117:19
|
||||||
|
|
|
|
||||||
LL | | false) => {}
|
LL | | false) => {}
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: unreachable pattern
|
error: unreachable pattern
|
||||||
--> $DIR/exhaustiveness-unreachable-pattern.rs:127:15
|
--> $DIR/exhaustiveness-unreachable-pattern.rs:125:15
|
||||||
|
|
|
|
||||||
LL | | true) => {}
|
LL | | true) => {}
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: unreachable pattern
|
error: unreachable pattern
|
||||||
--> $DIR/exhaustiveness-unreachable-pattern.rs:133:15
|
--> $DIR/exhaustiveness-unreachable-pattern.rs:131:15
|
||||||
|
|
|
|
||||||
LL | | true,
|
LL | | true,
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to 22 previous errors
|
error: aborting due to 21 previous errors
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user