Skip to content

Commit 7adc485

Browse files
committed
It has been found that rust-lang#13034 was flawed and caused regression rust-lang#13867. This patch reveres the changes made by it except the companion tests.
1 parent 8895f25 commit 7adc485

File tree

1 file changed

+8
-66
lines changed

1 file changed

+8
-66
lines changed

src/librustc/middle/trans/_match.rs

+8-66
Original file line numberDiff line numberDiff line change
@@ -289,42 +289,6 @@ fn opt_eq(tcx: &ty::ctxt, a: &Opt, b: &Opt) -> bool {
289289
}
290290
}
291291

292-
fn opt_overlap(tcx: &ty::ctxt, a: &Opt, b: &Opt) -> bool {
293-
match (a, b) {
294-
(&lit(a), &lit(b)) => {
295-
let a_expr = lit_to_expr(tcx, &a);
296-
let b_expr = lit_to_expr(tcx, &b);
297-
match const_eval::compare_lit_exprs(tcx, a_expr, b_expr) {
298-
Some(val1) => val1 == 0,
299-
None => fail!("opt_overlap: type mismatch"),
300-
}
301-
}
302-
303-
(&range(a1, a2), &range(b1, b2)) => {
304-
let m1 = const_eval::compare_lit_exprs(tcx, a1, b2);
305-
let m2 = const_eval::compare_lit_exprs(tcx, b1, a2);
306-
match (m1, m2) {
307-
// two ranges [a1, a2] and [b1, b2] overlap iff:
308-
// a1 <= b2 && b1 <= a2
309-
(Some(val1), Some(val2)) => (val1 <= 0 && val2 <= 0),
310-
_ => fail!("opt_overlap: type mismatch"),
311-
}
312-
}
313-
314-
(&range(a1, a2), &lit(b)) | (&lit(b), &range(a1, a2)) => {
315-
let b_expr = lit_to_expr(tcx, &b);
316-
let m1 = const_eval::compare_lit_exprs(tcx, a1, b_expr);
317-
let m2 = const_eval::compare_lit_exprs(tcx, a2, b_expr);
318-
match (m1, m2) {
319-
// b is in range [a1, a2] iff a1 <= b and b <= a2
320-
(Some(val1), Some(val2)) => (val1 <= 0 && 0 <= val2),
321-
_ => fail!("opt_overlap: type mismatch"),
322-
}
323-
}
324-
_ => fail!("opt_overlap: expect lit or range")
325-
}
326-
}
327-
328292
pub enum opt_result<'a> {
329293
single_result(Result<'a>),
330294
lower_bound(Result<'a>),
@@ -634,30 +598,16 @@ fn enter_opt<'a, 'b>(
634598
let tcx = bcx.tcx();
635599
let dummy = @ast::Pat {id: 0, node: ast::PatWild, span: DUMMY_SP};
636600
let mut i = 0;
637-
// By the virtue of fact that we are in `trans` already, `enter_opt` is able
638-
// to prune sub-match tree aggressively based on exact equality. But when it
639-
// comes to literal or range, that strategy may lead to wrong result if there
640-
// are guard function or multiple patterns inside tuple; in that case, pruning
641-
// based on the overlap of patterns is required.
642-
//
643-
// Ideally, when constructing the sub-match tree for certain arm, only those
644-
// arms beneath it matter. But that isn't how algorithm works right now and
645-
// all other arms are taken into consideration when computing `guarded` below.
646-
// That is ok since each round of `compile_submatch` guarantees to trim one
647-
// "column" of arm patterns and the algorithm will converge.
648-
let guarded = m.iter().any(|x| x.data.arm.guard.is_some());
649-
let multi_pats = m.len() > 0 && m[0].pats.len() > 1;
650601
enter_match(bcx, &tcx.def_map, m, col, val, |p| {
651602
let answer = match p.node {
652603
ast::PatEnum(..) |
653604
ast::PatIdent(_, _, None) if pat_is_const(&tcx.def_map, p) => {
654605
let const_def = tcx.def_map.borrow().get_copy(&p.id);
655606
let const_def_id = ast_util::def_id_of_def(const_def);
656-
let konst = lit(ConstLit(const_def_id));
657-
match guarded || multi_pats {
658-
false if opt_eq(tcx, &konst, opt) => Some(Vec::new()),
659-
true if opt_overlap(tcx, &konst, opt) => Some(Vec::new()),
660-
_ => None,
607+
if opt_eq(tcx, &lit(ConstLit(const_def_id)), opt) {
608+
Some(Vec::new())
609+
} else {
610+
None
661611
}
662612
}
663613
ast::PatEnum(_, ref subpats) => {
@@ -682,20 +632,12 @@ fn enter_opt<'a, 'b>(
682632
}
683633
}
684634
ast::PatLit(l) => {
685-
let lit_expr = lit(ExprLit(l));
686-
match guarded || multi_pats {
687-
false if opt_eq(tcx, &lit_expr, opt) => Some(Vec::new()),
688-
true if opt_overlap(tcx, &lit_expr, opt) => Some(Vec::new()),
689-
_ => None,
690-
}
635+
if opt_eq(tcx, &lit(ExprLit(l)), opt) { Some(Vec::new()) }
636+
else { None }
691637
}
692638
ast::PatRange(l1, l2) => {
693-
let rng = range(l1, l2);
694-
match guarded || multi_pats {
695-
false if opt_eq(tcx, &rng, opt) => Some(Vec::new()),
696-
true if opt_overlap(tcx, &rng, opt) => Some(Vec::new()),
697-
_ => None,
698-
}
639+
if opt_eq(tcx, &range(l1, l2), opt) { Some(Vec::new()) }
640+
else { None }
699641
}
700642
ast::PatStruct(_, ref field_pats, _) => {
701643
if opt_eq(tcx, &variant_opt(bcx, p.id), opt) {

0 commit comments

Comments
 (0)