Use otherwise_block
for or-pattern shortcutting
This commit is contained in:
parent
5fe2ca65cf
commit
764f086f2c
1 changed files with 8 additions and 3 deletions
|
@ -1585,18 +1585,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// We could add them to the or-candidates before the call to `test_or_pattern` but this
|
// We could add them to the or-candidates before the call to `test_or_pattern` but this
|
||||||
// would make it impossible to detect simplifiable or-patterns. That would guarantee
|
// would make it impossible to detect simplifiable or-patterns. That would guarantee
|
||||||
// exponentially large CFGs for cases like `(1 | 2, 3 | 4, ...)`.
|
// exponentially large CFGs for cases like `(1 | 2, 3 | 4, ...)`.
|
||||||
|
let mut last_otherwise = None;
|
||||||
|
first_candidate.visit_leaves(|leaf_candidate| {
|
||||||
|
last_otherwise = leaf_candidate.otherwise_block;
|
||||||
|
});
|
||||||
first_candidate.visit_leaves(|leaf_candidate| {
|
first_candidate.visit_leaves(|leaf_candidate| {
|
||||||
assert!(leaf_candidate.match_pairs.is_empty());
|
assert!(leaf_candidate.match_pairs.is_empty());
|
||||||
leaf_candidate.match_pairs.extend(remaining_match_pairs.iter().cloned());
|
leaf_candidate.match_pairs.extend(remaining_match_pairs.iter().cloned());
|
||||||
let or_start = leaf_candidate.pre_binding_block.unwrap();
|
let or_start = leaf_candidate.pre_binding_block.unwrap();
|
||||||
// In a case like `(P | Q, R | S)`, if `P` succeeds and `R | S` fails, we know `(Q,
|
// In a case like `(P | Q, R | S)`, if `P` succeeds and `R | S` fails, we know `(Q,
|
||||||
// R | S)` will fail too. If there is no guard, we skip testing of `Q` by branching
|
// R | S)` will fail too. If there is no guard, we skip testing of `Q` by branching
|
||||||
// directly to `remainder_start`. If there is a guard, `or_otherwise` can be reached
|
// directly to `last_otherwise`. If there is a guard,
|
||||||
// by guard failure as well, so we can't skip `Q`.
|
// `leaf_candidate.otherwise_block` can be reached by guard failure as well, so we
|
||||||
|
// can't skip `Q`.
|
||||||
let or_otherwise = if leaf_candidate.has_guard {
|
let or_otherwise = if leaf_candidate.has_guard {
|
||||||
leaf_candidate.otherwise_block.unwrap()
|
leaf_candidate.otherwise_block.unwrap()
|
||||||
} else {
|
} else {
|
||||||
remainder_start
|
last_otherwise.unwrap()
|
||||||
};
|
};
|
||||||
self.test_candidates_with_or(
|
self.test_candidates_with_or(
|
||||||
span,
|
span,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue