Skip to content

Commit 8150eb8

Browse files
committed
---
yaml --- r: 45008 b: refs/heads/master c: c4682dc h: refs/heads/master v: v3
1 parent 8222f9f commit 8150eb8

File tree

2 files changed

+52
-84
lines changed

2 files changed

+52
-84
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: 626ad484fecc5703f46812c7916fce6fec03ace9
2+
refs/heads/master: c4682dcabedaa5451d377aedfb9167f4f299e5e5
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a6d9689399d091c3265f00434a69c551a61c28dc
55
refs/heads/try: ef355f6332f83371e4acf04fc4eb940ab41d78d3

trunk/src/librustc/middle/trans/_match.rs

Lines changed: 51 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ use middle::const_eval;
151151
use middle::borrowck::root_map_key;
152152
use middle::pat_util::*;
153153
use middle::resolve::DefMap;
154+
use middle::trans::adt;
154155
use middle::trans::base::*;
155156
use middle::trans::build::*;
156157
use middle::trans::callee;
@@ -191,15 +192,15 @@ pub enum Lit {
191192
// range)
192193
pub enum Opt {
193194
lit(Lit),
194-
var(/* disr val */int, /* variant dids (enm, var) */(def_id, def_id)),
195+
var(/* disr val */int, adt::Repr),
195196
range(@ast::expr, @ast::expr),
196197
vec_len_eq(uint),
197198
vec_len_ge(uint)
198199
}
199200

200201
pub fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool {
201-
match (*a, *b) {
202-
(lit(a), lit(b)) => {
202+
match (a, b) {
203+
(&lit(a), &lit(b)) => {
203204
match (a, b) {
204205
(UnitLikeStructLit(a), UnitLikeStructLit(b)) => a == b,
205206
_ => {
@@ -233,13 +234,13 @@ pub fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool {
233234
}
234235
}
235236
}
236-
(range(a1, a2), range(b1, b2)) => {
237+
(&range(a1, a2), &range(b1, b2)) => {
237238
const_eval::compare_lit_exprs(tcx, a1, b1) == 0 &&
238239
const_eval::compare_lit_exprs(tcx, a2, b2) == 0
239240
}
240-
(var(a, _), var(b, _)) => a == b,
241-
(vec_len_eq(a), vec_len_eq(b)) => a == b,
242-
(vec_len_ge(a), vec_len_ge(b)) => a == b,
241+
(&var(a, _), &var(b, _)) => a == b,
242+
(&vec_len_eq(a), &vec_len_eq(b)) => a == b,
243+
(&vec_len_ge(a), &vec_len_ge(b)) => a == b,
243244
_ => false
244245
}
245246
}
@@ -267,8 +268,8 @@ pub fn trans_opt(bcx: block, o: &Opt) -> opt_result {
267268
let llval = consts::get_const_val(bcx.ccx(), lit_id);
268269
return single_result(rslt(bcx, llval));
269270
}
270-
var(disr_val, _) => {
271-
return single_result(rslt(bcx, C_int(ccx, disr_val)));
271+
var(disr_val, ref repr) => {
272+
return adt::trans_case(bcx, repr, disr_val);
272273
}
273274
range(l1, l2) => {
274275
return range_result(rslt(bcx, consts::const_expr(ccx, l1)),
@@ -283,13 +284,16 @@ pub fn trans_opt(bcx: block, o: &Opt) -> opt_result {
283284
}
284285
}
285286
286-
pub fn variant_opt(tcx: ty::ctxt, pat_id: ast::node_id) -> Opt {
287-
match tcx.def_map.get(&pat_id) {
287+
pub fn variant_opt(bcx: block, pat_id: ast::node_id)
288+
-> Opt {
289+
let ccx = bcx.ccx();
290+
match ccx.tcx.def_map.get(&pat_id) {
288291
ast::def_variant(enum_id, var_id) => {
289-
let variants = ty::enum_variants(tcx, enum_id);
292+
let variants = ty::enum_variants(ccx.tcx, enum_id);
290293
for vec::each(*variants) |v| {
291294
if var_id == v.id {
292-
return var(v.disr_val, (enum_id, var_id));
295+
return var(v.disr_val,
296+
adt::represent_node(bcx, pat_id))
293297
}
294298
}
295299
::core::util::unreachable();
@@ -298,7 +302,7 @@ pub fn variant_opt(tcx: ty::ctxt, pat_id: ast::node_id) -> Opt {
298302
return lit(UnitLikeStructLit(pat_id));
299303
}
300304
_ => {
301-
tcx.sess.bug(~"non-variant or struct in variant_opt()");
305+
ccx.sess.bug(~"non-variant or struct in variant_opt()");
302306
}
303307
}
304308
}
@@ -505,7 +509,7 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint,
505509
do enter_match(bcx, tcx.def_map, m, col, val) |p| {
506510
match /*bad*/copy p.node {
507511
ast::pat_enum(_, subpats) => {
508-
if opt_eq(tcx, &variant_opt(tcx, p.id), opt) {
512+
if opt_eq(tcx, &variant_opt(bcx, p.id), opt) {
509513
Some(option::get_or_default(subpats,
510514
vec::from_elem(variant_size,
511515
dummy)))
@@ -515,7 +519,7 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint,
515519
}
516520
ast::pat_ident(_, _, None)
517521
if pat_is_variant_or_struct(tcx.def_map, p) => {
518-
if opt_eq(tcx, &variant_opt(tcx, p.id), opt) {
522+
if opt_eq(tcx, &variant_opt(bcx, p.id), opt) {
519523
Some(~[])
520524
} else {
521525
None
@@ -537,7 +541,7 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint,
537541
if opt_eq(tcx, &range(l1, l2), opt) {Some(~[])} else {None}
538542
}
539543
ast::pat_struct(_, field_pats, _) => {
540-
if opt_eq(tcx, &variant_opt(tcx, p.id), opt) {
544+
if opt_eq(tcx, &variant_opt(bcx, p.id), opt) {
541545
// Look up the struct variant ID.
542546
let struct_id;
543547
match tcx.def_map.get(&p.id) {
@@ -762,8 +766,9 @@ pub fn enter_region(bcx: block,
762766
// Returns the options in one column of matches. An option is something that
763767
// needs to be conditionally matched at runtime; for example, the discriminant
764768
// on a set of enum variants or a literal.
765-
pub fn get_options(ccx: @CrateContext, m: &[@Match], col: uint) -> ~[Opt] {
766-
fn add_to_set(tcx: ty::ctxt, set: &DVec<Opt>, val: Opt) {
769+
pub fn get_options(bcx: block, m: &[@Match], col: uint) -> ~[Opt] {
770+
let ccx = bcx.ccx();
771+
fn add_to_set(tcx: ty::ctxt, set: &DVec<Opt>, +val: Opt) {
767772
if set.any(|l| opt_eq(tcx, l, &val)) {return;}
768773
set.push(val);
769774
}
@@ -781,7 +786,7 @@ pub fn get_options(ccx: @CrateContext, m: &[@Match], col: uint) -> ~[Opt] {
781786
match ccx.tcx.def_map.find(&cur.id) {
782787
Some(ast::def_variant(*)) => {
783788
add_to_set(ccx.tcx, &found,
784-
variant_opt(ccx.tcx, cur.id));
789+
variant_opt(bcx, cur.id));
785790
}
786791
Some(ast::def_struct(*)) => {
787792
add_to_set(ccx.tcx, &found,
@@ -800,7 +805,7 @@ pub fn get_options(ccx: @CrateContext, m: &[@Match], col: uint) -> ~[Opt] {
800805
match ccx.tcx.def_map.find(&cur.id) {
801806
Some(ast::def_variant(*)) => {
802807
add_to_set(ccx.tcx, &found,
803-
variant_opt(ccx.tcx, cur.id));
808+
variant_opt(bcx, cur.id));
804809
}
805810
_ => {}
806811
}
@@ -827,34 +832,13 @@ pub struct ExtractedBlock {
827832
}
828833
829834
pub fn extract_variant_args(bcx: block,
830-
pat_id: ast::node_id,
831-
vdefs: (def_id, def_id),
835+
repr: &adt::Repr,
836+
disr_val: int,
832837
val: ValueRef)
833-
-> ExtractedBlock {
834-
let (enm, evar) = vdefs;
838+
-> ExtractedBlock {
835839
let _icx = bcx.insn_ctxt("match::extract_variant_args");
836-
let ccx = *bcx.fcx.ccx;
837-
let enum_ty_substs = match ty::get(node_id_type(bcx, pat_id)).sty {
838-
ty::ty_enum(id, ref substs) => {
839-
assert id == enm;
840-
/*bad*/copy (*substs).tps
841-
}
842-
_ => bcx.sess().bug(~"extract_variant_args: pattern has non-enum type")
843-
};
844-
let mut blobptr = val;
845-
let variants = ty::enum_variants(ccx.tcx, enm);
846-
let size = ty::enum_variant_with_id(ccx.tcx, enm,
847-
evar).args.len();
848-
if size > 0u && (*variants).len() != 1u {
849-
let enumptr =
850-
PointerCast(bcx, val, T_opaque_enum_ptr(ccx));
851-
blobptr = GEPi(bcx, enumptr, [0u, 1u]);
852-
}
853-
let vdefs_tg = enm;
854-
let vdefs_var = evar;
855-
let args = do vec::from_fn(size) |i| {
856-
GEP_enum(bcx, blobptr, vdefs_tg, vdefs_var,
857-
/*bad*/copy enum_ty_substs, i)
840+
let args = do vec::from_fn(adt::num_args(repr, disr_val)) |i| {
841+
adt::trans_GEP(bcx, repr, val, disr_val, i)
858842
};
859843
860844
ExtractedBlock { vals: args, bcx: bcx }
@@ -1365,37 +1349,15 @@ pub fn compile_submatch(bcx: block,
13651349
}
13661350
13671351
// Decide what kind of branch we need
1368-
let opts = get_options(ccx, m, col);
1352+
let opts = get_options(bcx, m, col);
13691353
let mut kind = no_branch;
13701354
let mut test_val = val;
13711355
if opts.len() > 0u {
13721356
match opts[0] {
1373-
var(_, (enm, _)) => {
1374-
let variants = ty::enum_variants(tcx, enm);
1375-
if variants.len() == 1 {
1376-
kind = single;
1377-
} else {
1378-
let enumptr =
1379-
PointerCast(bcx, val, T_opaque_enum_ptr(ccx));
1380-
let discrimptr = GEPi(bcx, enumptr, [0u, 0u]);
1381-
1382-
1383-
assert variants.len() > 1;
1384-
let min_discrim = do variants.foldr(0) |&x, y| {
1385-
int::min(x.disr_val, y)
1386-
};
1387-
let max_discrim = do variants.foldr(0) |&x, y| {
1388-
int::max(x.disr_val, y)
1389-
};
1390-
1391-
test_val = LoadRangeAssert(bcx, discrimptr,
1392-
min_discrim as c_ulonglong,
1393-
(max_discrim + 1)
1394-
as c_ulonglong,
1395-
lib::llvm::True);
1396-
1397-
kind = switch;
1398-
}
1357+
var(_, ref repr) => {
1358+
let (the_kind, val_opt) = adt::trans_switch(bcx, repr, val);
1359+
kind = the_kind;
1360+
for val_opt.each |&tval| { test_val = tval; }
13991361
}
14001362
lit(_) => {
14011363
let pty = node_id_type(bcx, pat_id);
@@ -1544,11 +1506,12 @@ pub fn compile_submatch(bcx: block,
15441506
let mut size = 0u;
15451507
let mut unpacked = ~[];
15461508
match *opt {
1547-
var(_, vdef) => {
1548-
let args = extract_variant_args(opt_cx, pat_id, vdef, val);
1549-
size = args.vals.len();
1550-
unpacked = /*bad*/copy args.vals;
1551-
opt_cx = args.bcx;
1509+
var(disr_val, ref repr) => {
1510+
let ExtractedBlock {vals: argvals, bcx: new_bcx} =
1511+
extract_variant_args(opt_cx, repr, disr_val, val);
1512+
size = argvals.len();
1513+
unpacked = argvals;
1514+
opt_cx = new_bcx;
15521515
}
15531516
vec_len_eq(n) | vec_len_ge(n) => {
15541517
let tail = match *opt {
@@ -1757,10 +1720,15 @@ pub fn bind_irrefutable_pat(bcx: block,
17571720
}
17581721
ast::pat_enum(_, sub_pats) => {
17591722
match bcx.tcx().def_map.find(&pat.id) {
1760-
Some(ast::def_variant(*)) => {
1761-
let pat_def = ccx.tcx.def_map.get(&pat.id);
1762-
let vdefs = ast_util::variant_def_ids(pat_def);
1763-
let args = extract_variant_args(bcx, pat.id, vdefs, val);
1723+
Some(ast::def_variant(enum_id, var_id)) => {
1724+
let repr = adt::represent_node(bcx, pat.id);
1725+
let vinfo = ty::enum_variant_with_id(ccx.tcx,
1726+
enum_id,
1727+
var_id);
1728+
let args = extract_variant_args(bcx,
1729+
&repr,
1730+
vinfo.disr_val,
1731+
val);
17641732
for sub_pats.each |sub_pat| {
17651733
for vec::eachi(args.vals) |i, argval| {
17661734
bcx = bind_irrefutable_pat(bcx,

0 commit comments

Comments
 (0)