Skip to content

Commit 7296c06

Browse files
committed
---
yaml --- r: 6633 b: refs/heads/master c: 9a269a3 h: refs/heads/master i: 6631: 3b69b36 v: v3
1 parent f0dfcc2 commit 7296c06

18 files changed

+133
-80
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 8c966b7b18a5529c33dd9766460880bd681ab102
2+
refs/heads/master: 9a269a3aa8fe8140ad3f2fc2cfdfd68d6b40ec86

trunk/src/comp/middle/alias.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -585,8 +585,9 @@ fn pattern_roots(tcx: ty::ctxt, mut: option::t<unsafe_ty>, pat: @ast::pat)
585585
&set: [pattern_root]) {
586586
alt pat.node {
587587
ast::pat_wild. | ast::pat_lit(_) | ast::pat_range(_, _) {}
588-
ast::pat_bind(nm) {
588+
ast::pat_bind(nm, sub) {
589589
set += [{id: pat.id, name: nm, mut: mut, span: pat.span}];
590+
alt sub { some(p) { walk(tcx, mut, p, set); } _ {} }
590591
}
591592
ast::pat_tag(_, ps) | ast::pat_tup(ps) {
592593
for p in ps { walk(tcx, mut, p, set); }

trunk/src/comp/middle/check_alt.rs

+29-26
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import syntax::ast::*;
22
import syntax::ast_util::{variant_def_ids, dummy_sp, compare_lit_exprs,
33
lit_expr_eq};
44
import syntax::visit;
5+
import std::option::{some, none};
56

67
fn check_crate(tcx: ty::ctxt, crate: @crate) {
78
let v =
@@ -64,57 +65,58 @@ fn pattern_supersedes(tcx: ty::ctxt, a: @pat, b: @pat) -> bool {
6465
}
6566

6667
alt a.node {
67-
pat_wild. | pat_bind(_) { ret true; }
68+
pat_bind(_, some(p)) { pattern_supersedes(tcx, p, b) }
69+
pat_wild. | pat_bind(_, none.) { true }
6870
pat_lit(la) {
6971
alt b.node {
70-
pat_lit(lb) { ret lit_expr_eq(la, lb); }
71-
_ { ret false; }
72+
pat_lit(lb) { lit_expr_eq(la, lb) }
73+
_ { false }
7274
}
7375
}
7476
pat_tag(va, suba) {
7577
alt b.node {
7678
pat_tag(vb, subb) {
77-
ret tcx.def_map.get(a.id) == tcx.def_map.get(b.id) &&
78-
patterns_supersede(tcx, suba, subb);
79+
tcx.def_map.get(a.id) == tcx.def_map.get(b.id) &&
80+
patterns_supersede(tcx, suba, subb)
7981
}
80-
_ { ret false; }
82+
_ { false }
8183
}
8284
}
8385
pat_rec(suba, _) {
8486
alt b.node {
85-
pat_rec(subb, _) { ret field_patterns_supersede(tcx, suba, subb); }
86-
_ { ret false; }
87+
pat_rec(subb, _) { field_patterns_supersede(tcx, suba, subb) }
88+
_ { false }
8789
}
8890
}
8991
pat_tup(suba) {
9092
alt b.node {
91-
pat_tup(subb) { ret patterns_supersede(tcx, suba, subb); }
92-
_ { ret false; }
93+
pat_tup(subb) { patterns_supersede(tcx, suba, subb) }
94+
_ { false }
9395
}
9496
}
9597
pat_box(suba) {
9698
alt b.node {
97-
pat_box(subb) { ret pattern_supersedes(tcx, suba, subb); }
98-
_ { ret pattern_supersedes(tcx, suba, b); }
99+
pat_box(subb) { pattern_supersedes(tcx, suba, subb) }
100+
_ { pattern_supersedes(tcx, suba, b) }
99101
}
100102
}
101103
pat_uniq(suba) {
102104
alt b.node {
103-
pat_uniq(subb) { ret pattern_supersedes(tcx, suba, subb); }
104-
_ { ret pattern_supersedes(tcx, suba, b); }
105+
pat_uniq(subb) { pattern_supersedes(tcx, suba, subb) }
106+
_ { pattern_supersedes(tcx, suba, b) }
105107
}
106108
}
107109
pat_range(begina, enda) {
108110
alt b.node {
109111
pat_lit(lb) {
110-
ret compare_lit_exprs(begina, lb) <= 0 &&
111-
compare_lit_exprs(enda, lb) >= 0;
112+
compare_lit_exprs(begina, lb) <= 0 &&
113+
compare_lit_exprs(enda, lb) >= 0
112114
}
113115
pat_range(beginb, endb) {
114-
ret compare_lit_exprs(begina, beginb) <= 0 &&
115-
compare_lit_exprs(enda, endb) >= 0;
116+
compare_lit_exprs(begina, beginb) <= 0 &&
117+
compare_lit_exprs(enda, endb) >= 0
116118
}
117-
_ { ret false; }
119+
_ { false }
118120
}
119121
}
120122
}
@@ -130,25 +132,26 @@ fn check_local(tcx: ty::ctxt, loc: @local, &&s: (), v: visit::vt<()>) {
130132

131133
fn is_refutable(tcx: ty::ctxt, pat: @pat) -> bool {
132134
alt pat.node {
133-
pat_wild. | pat_bind(_) { ret false; }
134-
pat_lit(_) { ret true; }
135-
pat_box(sub) { ret is_refutable(tcx, sub); }
136-
pat_uniq(sub) { ret is_refutable(tcx, sub); }
135+
pat_box(sub) | pat_uniq(sub) | pat_bind(_, some(sub)) {
136+
is_refutable(tcx, sub)
137+
}
138+
pat_wild. | pat_bind(_, none.) { false }
139+
pat_lit(_) { true }
137140
pat_rec(fields, _) {
138141
for field: field_pat in fields {
139142
if is_refutable(tcx, field.pat) { ret true; }
140143
}
141-
ret false;
144+
false
142145
}
143146
pat_tup(elts) {
144147
for elt in elts { if is_refutable(tcx, elt) { ret true; } }
145-
ret false;
148+
false
146149
}
147150
pat_tag(_, args) {
148151
let vdef = variant_def_ids(tcx.def_map.get(pat.id));
149152
if std::vec::len(ty::tag_variants(tcx, vdef.tg)) != 1u { ret true; }
150153
for p: @pat in args { if is_refutable(tcx, p) { ret true; } }
151-
ret false;
154+
false
152155
}
153156
}
154157
}

trunk/src/comp/middle/resolve.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,7 @@ fn lookup_in_ty_params(name: ident, ty_params: [ast::ty_param]) ->
819819
fn lookup_in_pat(name: ident, pat: @ast::pat) -> option::t<def_id> {
820820
let found = none;
821821
ast_util::pat_bindings(pat) {|bound|
822-
let p_name = alt bound.node { ast::pat_bind(n) { n } };
822+
let p_name = alt bound.node { ast::pat_bind(n, _) { n } };
823823
if str::eq(p_name, name) { found = some(local_def(bound.id)); }
824824
};
825825
ret found;
@@ -1376,7 +1376,7 @@ fn check_item(e: @env, i: @ast::item, &&x: (), v: vt<()>) {
13761376

13771377
fn check_pat(ch: checker, p: @ast::pat) {
13781378
ast_util::pat_bindings(p) {|p|
1379-
let ident = alt p.node { pat_bind(n) { n } };
1379+
let ident = alt p.node { pat_bind(n, _) { n } };
13801380
add_name(ch, p.span, ident);
13811381
};
13821382
}
@@ -1424,7 +1424,7 @@ fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) {
14241424
let local_values = checker(*e, "value");
14251425
for (_, loc) in locs {
14261426
ast_util::pat_bindings(loc.node.pat) {|p|
1427-
let ident = alt p.node { pat_bind(n) { n } };
1427+
let ident = alt p.node { pat_bind(n, _) { n } };
14281428
add_name(local_values, p.span, ident);
14291429
check_name(values, p.span, ident);
14301430
};

trunk/src/comp/middle/trans.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4702,7 +4702,7 @@ fn alloc_ty(cx: @block_ctxt, t: ty::t) -> result {
47024702
fn alloc_local(cx: @block_ctxt, local: @ast::local) -> @block_ctxt {
47034703
let t = node_id_type(bcx_ccx(cx), local.node.id);
47044704
let is_simple = alt local.node.pat.node {
4705-
ast::pat_bind(_) { true } _ { false }
4705+
ast::pat_bind(_, none.) { true } _ { false }
47064706
};
47074707
// Do not allocate space for locals that can be kept immediate.
47084708
let ccx = bcx_ccx(cx);
@@ -4716,7 +4716,7 @@ fn alloc_local(cx: @block_ctxt, local: @ast::local) -> @block_ctxt {
47164716
}
47174717
let r = alloc_ty(cx, t);
47184718
alt local.node.pat.node {
4719-
ast::pat_bind(ident) {
4719+
ast::pat_bind(ident, none.) {
47204720
if bcx_ccx(cx).sess.get_opts().debuginfo {
47214721
let _: () = str::as_buf(ident, {|buf|
47224722
llvm::LLVMSetValueName(r.val, buf)

trunk/src/comp/middle/trans_alt.rs

+49-19
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,31 @@ type match_branch =
8888
id_map: ast_util::pat_id_map}};
8989
type match = [match_branch];
9090

91-
fn matches_always(p: @ast::pat) -> bool {
92-
ret alt p.node {
93-
ast::pat_wild. { true }
94-
ast::pat_bind(_) { true }
95-
ast::pat_rec(_, _) { true }
96-
ast::pat_tup(_) { true }
97-
_ { false }
98-
};
91+
fn has_nested_bindings(m: match, col: uint) -> bool {
92+
for br in m {
93+
alt br.pats[col].node {
94+
ast::pat_bind(_, some(_)) { ret true; }
95+
_ {}
96+
}
97+
}
98+
ret false;
99+
}
100+
101+
fn expand_nested_bindings(m: match, col: uint, val: ValueRef) -> match {
102+
let result = [];
103+
for br in m {
104+
alt br.pats[col].node {
105+
ast::pat_bind(name, some(inner)) {
106+
let pats = vec::slice(br.pats, 0u, col) + [inner] +
107+
vec::slice(br.pats, col + 1u, vec::len(br.pats));
108+
result += [@{pats: pats,
109+
bound: br.bound + [{ident: name, val: val}]
110+
with *br}];
111+
}
112+
_ { result += [br]; }
113+
}
114+
}
115+
result
99116
}
100117

101118
type enter_pat = fn@(@ast::pat) -> option::t<[@ast::pat]>;
@@ -109,7 +126,7 @@ fn enter_match(m: match, col: uint, val: ValueRef, e: enter_pat) -> match {
109126
vec::slice(br.pats, col + 1u, vec::len(br.pats));
110127
let new_br = @{pats: pats,
111128
bound: alt br.pats[col].node {
112-
ast::pat_bind(name) {
129+
ast::pat_bind(name, none.) {
113130
br.bound + [{ident: name, val: val}]
114131
}
115132
_ { br.bound }
@@ -123,6 +140,13 @@ fn enter_match(m: match, col: uint, val: ValueRef, e: enter_pat) -> match {
123140
}
124141

125142
fn enter_default(m: match, col: uint, val: ValueRef) -> match {
143+
fn matches_always(p: @ast::pat) -> bool {
144+
ret alt p.node {
145+
ast::pat_wild. | ast::pat_bind(_, none.) | ast::pat_rec(_, _) |
146+
ast::pat_tup(_) { true }
147+
_ { false }
148+
};
149+
}
126150
fn e(p: @ast::pat) -> option::t<[@ast::pat]> {
127151
ret if matches_always(p) { some([]) } else { none };
128152
}
@@ -303,18 +327,17 @@ type exit_node = {bound: bind_map, from: BasicBlockRef, to: BasicBlockRef};
303327
type mk_fail = fn@() -> BasicBlockRef;
304328

305329
fn pick_col(m: match) -> uint {
330+
fn score(p: @ast::pat) -> uint {
331+
alt p.node {
332+
ast::pat_lit(_) | ast::pat_tag(_, _) | ast::pat_range(_, _) { 1u }
333+
ast::pat_bind(_, some(p)) { score(p) }
334+
_ { 0u }
335+
}
336+
}
306337
let scores = vec::init_elt_mut(0u, vec::len(m[0].pats));
307338
for br: match_branch in m {
308339
let i = 0u;
309-
for p: @ast::pat in br.pats {
310-
alt p.node {
311-
ast::pat_lit(_) | ast::pat_tag(_, _) | ast::pat_range(_, _) {
312-
scores[i] += 1u;
313-
}
314-
_ { }
315-
}
316-
i += 1u;
317-
}
340+
for p: @ast::pat in br.pats { scores[i] += score(p); i += 1u; }
318341
}
319342
let max_score = 0u;
320343
let best_col = 0u;
@@ -368,6 +391,9 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
368391

369392
let col = pick_col(m);
370393
let val = vals[col];
394+
let m = has_nested_bindings(m, col) ?
395+
expand_nested_bindings(m, col, val) : m;
396+
371397
let vals_left =
372398
vec::slice(vals, 0u, col) +
373399
vec::slice(vals, col + 1u, vec::len(vals));
@@ -662,7 +688,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
662688
make_copy: bool) -> @block_ctxt {
663689
let ccx = bcx.fcx.lcx.ccx, bcx = bcx;
664690
alt pat.node {
665-
ast::pat_bind(_) {
691+
ast::pat_bind(_, inner) {
666692
if make_copy || ccx.copy_map.contains_key(pat.id) {
667693
let ty = ty::node_id_to_monotype(ccx.tcx, pat.id);
668694
// FIXME: Could constrain pat_bind to make this
@@ -676,6 +702,10 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
676702
bcx.fcx.lllocals.insert(pat.id, local_mem(alloc));
677703
trans_common::add_clean(bcx, alloc, ty);
678704
} else { bcx.fcx.lllocals.insert(pat.id, local_mem(val)); }
705+
alt inner {
706+
some(pat) { bcx = bind_irrefutable_pat(bcx, pat, val, true); }
707+
_ {}
708+
}
679709
}
680710
ast::pat_tag(_, sub) {
681711
if vec::len(sub) == 0u { ret bcx; }

trunk/src/comp/middle/tstate/auxiliary.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,7 @@ type binding = {lhs: [inst], rhs: option::t<initializer>};
10481048
fn local_to_bindings(loc: @local) -> binding {
10491049
let lhs = [];
10501050
pat_bindings(loc.node.pat) {|p|
1051-
let ident = alt p.node { pat_bind(name) { name } };
1051+
let ident = alt p.node { pat_bind(name, _) { name } };
10521052
lhs += [{ident: ident, node: p.id}];
10531053
};
10541054
{lhs: lhs, rhs: loc.node.init}

trunk/src/comp/middle/tstate/collect_locals.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ type ctxt = {cs: @mutable [sp_constr], tcx: ty::ctxt};
1212

1313
fn collect_local(loc: @local, cx: ctxt, v: visit::vt<ctxt>) {
1414
pat_bindings(loc.node.pat) {|p|
15-
let ident = alt p.node { pat_bind(id) { id } };
15+
let ident = alt p.node { pat_bind(id, _) { id } };
1616
log "collect_local: pushing " + ident;;
1717
*cx.cs += [respan(loc.span, ninit(p.id, ident))];
1818
};

trunk/src/comp/middle/tstate/pre_post_conditions.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ fn find_pre_post_loop(fcx: fn_ctxt, l: @local, index: @expr, body: blk,
108108
find_pre_post_expr(fcx, index);
109109
find_pre_post_block(fcx, body);
110110
pat_bindings(l.node.pat) {|p|
111-
let ident = alt p.node { pat_bind(id) { id } };
111+
let ident = alt p.node { pat_bind(id, _) { id } };
112112
let v_init = ninit(p.id, ident);
113113
relax_precond_block(fcx, bit_num(fcx, v_init) as node_id, body);
114114
// Hack: for-loop index variables are frequently ignored,
@@ -579,11 +579,7 @@ fn find_pre_post_stmt(fcx: fn_ctxt, s: stmt) {
579579
/* FIXME: This won't be necessary when typestate
580580
works well enough for pat_bindings to return a
581581
refinement-typed thing. */
582-
let ident = alt pat.node {
583-
pat_bind(n) { n }
584-
_ { fcx.ccx.tcx.sess.span_bug(pat.span,
585-
"Impossible LHS"); }
586-
};
582+
let ident = alt pat.node { pat_bind(n, _) { n } };
587583
alt p {
588584
some(p) {
589585
copy_in_postcond(fcx, id,
@@ -612,14 +608,10 @@ fn find_pre_post_stmt(fcx: fn_ctxt, s: stmt) {
612608
postconds of the RHSs themselves */
613609
pat_bindings(alocal.node.pat) {|pat|
614610
alt pat.node {
615-
pat_bind(n) {
611+
pat_bind(n, _) {
616612
set_in_postcond(bit_num(fcx, ninit(pat.id, n)),
617613
prev_pp);
618614
}
619-
_ {
620-
fcx.ccx.tcx.sess.span_bug(pat.span,
621-
"Impossible LHS");
622-
}
623615
}
624616
};
625617
copy_pre_post_(fcx.ccx, id, prev_pp.precondition,

trunk/src/comp/middle/tstate/states.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ fn find_pre_post_state_loop(fcx: fn_ctxt, pres: prestate, l: @local,
206206
// in the body
207207
let index_post = tritv_clone(expr_poststate(fcx.ccx, index));
208208
pat_bindings(l.node.pat) {|p|
209-
let ident = alt p.node { pat_bind(name) { name } };
209+
let ident = alt p.node { pat_bind(name, _) { name } };
210210
set_in_poststate_ident(fcx, p.id, ident, index_post);
211211
};
212212

trunk/src/comp/middle/typeck.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1178,7 +1178,7 @@ fn gather_locals(ccx: @crate_ctxt, f: ast::_fn, id: ast::node_id,
11781178
let visit_pat =
11791179
lambda (p: @ast::pat, &&e: (), v: visit::vt<()>) {
11801180
alt p.node {
1181-
ast::pat_bind(_) { assign(p.id, none); }
1181+
ast::pat_bind(_, _) { assign(p.id, none); }
11821182
_ {/* no-op */ }
11831183
}
11841184
visit::visit_pat(p, e, v);
@@ -1248,7 +1248,7 @@ fn check_pat(fcx: @fn_ctxt, map: ast_util::pat_id_map, pat: @ast::pat,
12481248
}
12491249
write::ty_only_fixup(fcx, pat.id, b_ty);
12501250
}
1251-
ast::pat_bind(name) {
1251+
ast::pat_bind(name, sub) {
12521252
let vid = lookup_local(fcx, pat.span, pat.id);
12531253
let typ = ty::mk_var(fcx.ccx.tcx, vid);
12541254
typ = demand::simple(fcx, pat.span, expected, typ);
@@ -1260,6 +1260,10 @@ fn check_pat(fcx: @fn_ctxt, map: ast_util::pat_id_map, pat: @ast::pat,
12601260
typ = demand::simple(fcx, pat.span, ct, typ);
12611261
}
12621262
write::ty_only_fixup(fcx, pat.id, typ);
1263+
alt sub {
1264+
some(p) { check_pat(fcx, map, p, expected); }
1265+
_ {}
1266+
}
12631267
}
12641268
ast::pat_tag(path, subpats) {
12651269
// Typecheck the path.

0 commit comments

Comments
 (0)