Skip to content

Commit 86f379d

Browse files
committed
---
yaml --- r: 41999 b: refs/heads/master c: cff4f14 h: refs/heads/master i: 41997: 9cd3f5d 41995: a169c1e 41991: a83a859 41983: 3f927ed v: v3
1 parent 0451ae0 commit 86f379d

File tree

2 files changed

+149
-140
lines changed

2 files changed

+149
-140
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 2d33e308ac8bd4e59a54feaddf301488c215f90b
2+
refs/heads/master: cff4f1476ee9b96433d7dfa23afe5d9fdd45b554
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 2f46b763da2c098913884f101b6d71d69af41b49
55
refs/heads/try: 3d5418789064fdb463e872a4e651af1c628a3650

trunk/src/librustc/middle/check_match.rs

Lines changed: 148 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -481,161 +481,170 @@ fn wild() -> @pat {
481481
@pat {id: 0, node: pat_wild, span: ast_util::dummy_sp()}
482482
}
483483

484-
fn specialize(cx: @MatchCheckCtxt, r: ~[@pat], ctor_id: ctor, arity: uint,
484+
fn specialize(cx: @MatchCheckCtxt, +r: ~[@pat], ctor_id: ctor, arity: uint,
485485
left_ty: ty::t) -> Option<~[@pat]> {
486-
let r0 = raw_pat(r[0]);
487-
match /*bad*/copy r0.node {
488-
pat_wild => Some(vec::append(vec::from_elem(arity, wild()),
489-
vec::tail(r))),
490-
pat_ident(_, _, _) => {
491-
match cx.tcx.def_map.find(r0.id) {
492-
Some(def_variant(_, id)) => {
493-
if variant(id) == ctor_id { Some(vec::tail(r)) }
494-
else { None }
495-
}
496-
Some(def_const(did)) => {
497-
let const_expr = lookup_const_by_id(cx.tcx, did).get();
498-
let e_v = eval_const_expr(cx.tcx, const_expr);
499-
let match_ = match ctor_id {
500-
val(ref v) => compare_const_vals(e_v, (*v)) == 0,
501-
range(ref c_lo, ref c_hi) => {
502-
compare_const_vals((*c_lo), e_v) >= 0 &&
503-
compare_const_vals((*c_hi), e_v) <= 0
486+
// Sad, but I can't get rid of this easily
487+
let mut r0 = copy *raw_pat(r[0]);
488+
match r0 {
489+
pat{id: pat_id, node: n, span: pat_span} =>
490+
match n {
491+
pat_wild => Some(vec::append(vec::from_elem(arity, wild()),
492+
vec::tail(r))),
493+
pat_ident(_, _, _) => {
494+
match cx.tcx.def_map.find(pat_id) {
495+
Some(def_variant(_, id)) => {
496+
if variant(id) == ctor_id { Some(vec::tail(r)) }
497+
else { None }
498+
}
499+
Some(def_const(did)) => {
500+
let const_expr =
501+
lookup_const_by_id(cx.tcx, did).get();
502+
let e_v = eval_const_expr(cx.tcx, const_expr);
503+
let match_ = match ctor_id {
504+
val(ref v) => compare_const_vals(e_v, (*v)) == 0,
505+
range(ref c_lo, ref c_hi) => {
506+
compare_const_vals((*c_lo), e_v) >= 0 &&
507+
compare_const_vals((*c_hi), e_v) <= 0
508+
}
509+
single => true,
510+
_ => fail ~"type error"
511+
};
512+
if match_ { Some(vec::tail(r)) } else { None }
513+
}
514+
_ => Some(vec::append(vec::from_elem(arity, wild()),
515+
vec::tail(r)))
504516
}
505-
single => true,
506-
_ => fail ~"type error"
507-
};
508-
if match_ { Some(vec::tail(r)) } else { None }
509-
}
510-
_ => Some(vec::append(vec::from_elem(arity, wild()), vec::tail(r)))
511-
}
512-
}
513-
pat_enum(_, args) => {
514-
match cx.tcx.def_map.get(r0.id) {
515-
def_variant(_, id) if variant(id) == ctor_id => {
516-
let args = match args {
517-
Some(args) => args,
518-
None => vec::from_elem(arity, wild())
519-
};
520-
Some(vec::append(args, vec::tail(r)))
521-
}
522-
def_variant(_, _) => None,
523-
def_struct(*) => {
524-
// XXX: Is this right? --pcw
525-
let new_args;
526-
match args {
527-
Some(args) => new_args = args,
528-
None => new_args = vec::from_elem(arity, wild())
529-
}
530-
Some(vec::append(new_args, vec::tail(r)))
531-
}
532-
_ => None
533-
}
534-
}
535-
pat_rec(flds, _) => {
536-
let ty_flds = match /*bad*/copy ty::get(left_ty).sty {
537-
ty::ty_rec(flds) => flds,
538-
_ => fail ~"bad type for pat_rec"
539-
};
540-
let args = vec::map(ty_flds, |ty_fld| {
541-
match vec::find(flds, |f| f.ident == ty_fld.ident ) {
542-
Some(f) => f.pat,
543-
_ => wild()
544517
}
545-
});
546-
Some(vec::append(args, vec::tail(r)))
547-
}
548-
pat_struct(_, flds, _) => {
549-
// Is this a struct or an enum variant?
550-
match cx.tcx.def_map.get(r0.id) {
551-
def_variant(_, variant_id) => {
552-
if variant(variant_id) == ctor_id {
553-
// XXX: Is this right? --pcw
554-
let args = flds.map(|ty_field| {
555-
match vec::find(flds, |f| f.ident == ty_field.ident) {
556-
Some(f) => f.pat,
557-
_ => wild()
518+
pat_enum(_, args) => {
519+
match cx.tcx.def_map.get(pat_id) {
520+
def_variant(_, id) if variant(id) == ctor_id => {
521+
let args = match args {
522+
Some(args) => args,
523+
None => vec::from_elem(arity, wild())
524+
};
525+
Some(vec::append(args, vec::tail(r)))
526+
}
527+
def_variant(_, _) => None,
528+
def_struct(*) => {
529+
// XXX: Is this right? --pcw
530+
let new_args;
531+
match args {
532+
Some(args) => new_args = args,
533+
None => new_args = vec::from_elem(arity, wild())
558534
}
559-
});
560-
Some(vec::append(args, vec::tail(r)))
561-
} else {
562-
None
535+
Some(vec::append(new_args, vec::tail(r)))
536+
}
537+
_ => None
563538
}
564539
}
565-
_ => {
566-
// Grab the class data that we care about.
567-
let class_fields, class_id;
568-
match ty::get(left_ty).sty {
569-
ty::ty_struct(cid, _) => {
570-
class_id = cid;
571-
class_fields = ty::lookup_struct_fields(cx.tcx,
572-
class_id);
540+
pat_rec(ref flds, _) => {
541+
let ty_flds = match /*bad*/copy ty::get(left_ty).sty {
542+
ty::ty_rec(flds) => flds,
543+
_ => fail ~"bad type for pat_rec"
544+
};
545+
let args = vec::map(ty_flds, |ty_fld| {
546+
match flds.find(|f| f.ident == ty_fld.ident) {
547+
Some(f) => f.pat,
548+
_ => wild()
549+
}
550+
});
551+
Some(vec::append(args, vec::tail(r)))
552+
}
553+
pat_struct(_, ref flds, _) => {
554+
// Is this a struct or an enum variant?
555+
match cx.tcx.def_map.get(pat_id) {
556+
def_variant(_, variant_id) => {
557+
if variant(variant_id) == ctor_id {
558+
// XXX: Is this right? --pcw
559+
let args = flds.map(|ty_field| {
560+
match flds.find(|f|
561+
f.ident == ty_field.ident) {
562+
Some(f) => f.pat,
563+
_ => wild()
564+
}
565+
});
566+
Some(vec::append(args, vec::tail(r)))
567+
} else {
568+
None
569+
}
573570
}
574571
_ => {
575-
cx.tcx.sess.span_bug(r0.span, ~"struct pattern \
576-
didn't resolve to a \
577-
struct");
572+
// Grab the class data that we care about.
573+
let class_fields, class_id;
574+
match ty::get(left_ty).sty {
575+
ty::ty_struct(cid, _) => {
576+
class_id = cid;
577+
class_fields =
578+
ty::lookup_struct_fields(cx.tcx,
579+
class_id);
580+
}
581+
_ => {
582+
cx.tcx.sess.span_bug(pat_span,
583+
~"struct pattern didn't resolve to a struct");
584+
}
585+
}
586+
let args = vec::map(class_fields, |class_field| {
587+
match flds.find(|f|
588+
f.ident == class_field.ident) {
589+
Some(f) => f.pat,
590+
_ => wild()
591+
}
592+
});
593+
Some(vec::append(args, vec::tail(r)))
578594
}
579595
}
580-
let args = vec::map(class_fields, |class_field| {
581-
match vec::find(flds, |f| f.ident == class_field.ident ) {
582-
Some(f) => f.pat,
583-
_ => wild()
596+
}
597+
pat_tup(args) => Some(vec::append(args, vec::tail(r))),
598+
pat_box(a) | pat_uniq(a) | pat_region(a) =>
599+
Some(vec::append(~[a], vec::tail(r))),
600+
pat_lit(expr) => {
601+
let e_v = eval_const_expr(cx.tcx, expr);
602+
let match_ = match ctor_id {
603+
val(ref v) => compare_const_vals(e_v, (*v)) == 0,
604+
range(ref c_lo, ref c_hi) => {
605+
compare_const_vals((*c_lo), e_v) >= 0 &&
606+
compare_const_vals((*c_hi), e_v) <= 0
584607
}
585-
});
586-
Some(vec::append(args, vec::tail(r)))
608+
single => true,
609+
_ => fail ~"type error"
610+
};
611+
if match_ { Some(vec::tail(r)) } else { None }
587612
}
588-
}
589-
}
590-
pat_tup(args) => Some(vec::append(args, vec::tail(r))),
591-
pat_box(a) | pat_uniq(a) | pat_region(a) =>
592-
Some(vec::append(~[a], vec::tail(r))),
593-
pat_lit(expr) => {
594-
let e_v = eval_const_expr(cx.tcx, expr);
595-
let match_ = match ctor_id {
596-
val(ref v) => compare_const_vals(e_v, (*v)) == 0,
597-
range(ref c_lo, ref c_hi) => {
598-
compare_const_vals((*c_lo), e_v) >= 0 &&
599-
compare_const_vals((*c_hi), e_v) <= 0
600-
}
601-
single => true,
602-
_ => fail ~"type error"
603-
};
604-
if match_ { Some(vec::tail(r)) } else { None }
605-
}
606-
pat_range(lo, hi) => {
607-
let (c_lo, c_hi) = match ctor_id {
608-
val(ref v) => ((/*bad*/copy *v), (/*bad*/copy *v)),
609-
range(ref lo, ref hi) => ((/*bad*/copy *lo), (/*bad*/copy *hi)),
610-
single => return Some(vec::tail(r)),
611-
_ => fail ~"type error"
612-
};
613-
let v_lo = eval_const_expr(cx.tcx, lo),
614-
v_hi = eval_const_expr(cx.tcx, hi);
615-
let match_ = compare_const_vals(c_lo, v_lo) >= 0 &&
613+
pat_range(lo, hi) => {
614+
let (c_lo, c_hi) = match ctor_id {
615+
val(ref v) => ((/*bad*/copy *v), (/*bad*/copy *v)),
616+
range(ref lo, ref hi) =>
617+
((/*bad*/copy *lo), (/*bad*/copy *hi)),
618+
single => return Some(vec::tail(r)),
619+
_ => fail ~"type error"
620+
};
621+
let v_lo = eval_const_expr(cx.tcx, lo),
622+
v_hi = eval_const_expr(cx.tcx, hi);
623+
let match_ = compare_const_vals(c_lo, v_lo) >= 0 &&
616624
compare_const_vals(c_hi, v_hi) <= 0;
617-
if match_ { Some(vec::tail(r)) } else { None }
625+
if match_ { Some(vec::tail(r)) } else { None }
618626
}
619-
pat_vec(elems, tail) => {
620-
match ctor_id {
621-
vec(_) => {
622-
if elems.len() < arity && tail.is_some() {
623-
// XXX: Bad copy.
624-
Some(vec::append(
625-
vec::append(copy elems, vec::from_elem(
626-
arity - elems.len(), wild()
627-
)),
628-
vec::tail(r)
629-
))
630-
} else if elems.len() == arity {
631-
Some(vec::append(elems, vec::tail(r)))
632-
} else {
633-
None
627+
pat_vec(elems, tail) => {
628+
match ctor_id {
629+
vec(_) => {
630+
let num_elements = elems.len();
631+
if num_elements < arity && tail.is_some() {
632+
Some(vec::append(
633+
vec::append(elems, vec::from_elem(
634+
arity - num_elements, wild()
635+
)),
636+
vec::tail(r)
637+
))
638+
} else if num_elements == arity {
639+
Some(vec::append(elems, vec::tail(r)))
640+
} else {
641+
None
642+
}
643+
}
644+
_ => None
645+
}
634646
}
635-
}
636-
_ => None
637647
}
638-
}
639648
}
640649
}
641650

0 commit comments

Comments
 (0)