Skip to content

Commit 0a26edc

Browse files
committed
Fix trans for region patterns (&P)
1 parent ba3eebd commit 0a26edc

File tree

9 files changed

+99
-40
lines changed

9 files changed

+99
-40
lines changed

src/libsyntax/parse/token.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ type ident_interner = util::interner::interner<@~str>;
331331
* so we have to use a unique number. See taskgroup_key! in task.rs
332332
* for another case of this. */
333333
macro_rules! interner_key (
334-
() => (cast::transmute::<(uint, uint), &fn(+@@token::ident_interner)>(
334+
() => (cast::transmute::<(uint, uint), &fn(+v: @@token::ident_interner)>(
335335
(-3 as uint, 0u)))
336336
)
337337

src/rustc/middle/trans/alt.rs

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,31 @@ fn enter_uniq(bcx: block, dm: DefMap, m: &[@Match/&r],
487487
}
488488
}
489489

490+
fn enter_region(bcx: block, dm: DefMap, m: &[@Match/&r],
491+
col: uint, val: ValueRef)
492+
-> ~[@Match/&r]
493+
{
494+
debug!("enter_region(bcx=%s, m=%s, col=%u, val=%?)",
495+
bcx.to_str(),
496+
matches_to_str(bcx, m),
497+
col,
498+
bcx.val_str(val));
499+
let _indenter = indenter();
500+
501+
let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
502+
do enter_match(bcx, dm, m, col, val) |p| {
503+
match p.node {
504+
ast::pat_region(sub) => {
505+
Some(~[sub])
506+
}
507+
_ => {
508+
assert_is_binding_or_wild(bcx, p);
509+
Some(~[dummy])
510+
}
511+
}
512+
}
513+
}
514+
490515
fn get_options(ccx: @crate_ctxt, m: &[@Match], col: uint) -> ~[Opt] {
491516
fn add_to_set(tcx: ty::ctxt, set: &DVec<Opt>, val: Opt) {
492517
if set.any(|l| opt_eq(tcx, &l, &val)) {return;}
@@ -585,34 +610,35 @@ fn root_pats_as_necessary(bcx: block, m: &[@Match],
585610
}
586611
}
587612

588-
fn any_box_pat(m: &[@Match], col: uint) -> bool {
589-
for vec::each(m) |br| {
590-
match br.pats[col].node {
591-
ast::pat_box(_) => return true,
592-
_ => ()
593-
}
613+
// Macro for deciding whether any of the remaining matches fit a given kind of
614+
// pattern. Note that, because the macro is well-typed, either ALL of the
615+
// matches should fit that sort of pattern or NONE (however, some of the
616+
// matches may be wildcards like _ or identifiers).
617+
macro_rules! any_pat (
618+
($m:expr, $pattern:pat) => {
619+
vec::any($m, |br| {
620+
match br.pats[col].node {
621+
$pattern => true,
622+
_ => false
623+
}
624+
})
594625
}
595-
return false;
626+
)
627+
628+
fn any_box_pat(m: &[@Match], col: uint) -> bool {
629+
any_pat!(m, ast::pat_box(_))
596630
}
597631

598632
fn any_uniq_pat(m: &[@Match], col: uint) -> bool {
599-
for vec::each(m) |br| {
600-
match br.pats[col].node {
601-
ast::pat_uniq(_) => return true,
602-
_ => ()
603-
}
604-
}
605-
return false;
633+
any_pat!(m, ast::pat_uniq(_))
634+
}
635+
636+
fn any_region_pat(m: &[@Match], col: uint) -> bool {
637+
any_pat!(m, ast::pat_region(_))
606638
}
607639

608640
fn any_tup_pat(m: &[@Match], col: uint) -> bool {
609-
for vec::each(m) |br| {
610-
match br.pats[col].node {
611-
ast::pat_tup(_) => return true,
612-
_ => ()
613-
}
614-
}
615-
return false;
641+
any_pat!(m, ast::pat_tup(_))
616642
}
617643

618644
type mk_fail = fn@() -> BasicBlockRef;
@@ -940,6 +966,13 @@ fn compile_submatch(bcx: block,
940966
return;
941967
}
942968
969+
if any_region_pat(m, col) {
970+
let loaded_val = Load(bcx, val);
971+
compile_submatch(bcx, enter_region(bcx, dm, m, col, val),
972+
vec::append(~[loaded_val], vals_left), chk);
973+
return;
974+
}
975+
943976
// Decide what kind of branch we need
944977
let opts = get_options(ccx, m, col);
945978
let mut kind = no_branch;
@@ -1248,12 +1281,15 @@ fn bind_irrefutable_pat(bcx: block, pat: @ast::pat, val: ValueRef,
12481281
bcx = bind_irrefutable_pat(bcx, *elem, fldptr, make_copy);
12491282
}
12501283
}
1251-
ast::pat_box(inner) | ast::pat_uniq(inner) |
1252-
ast::pat_region(inner) => {
1284+
ast::pat_box(inner) | ast::pat_uniq(inner) => {
12531285
let llbox = Load(bcx, val);
12541286
let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]);
12551287
bcx = bind_irrefutable_pat(bcx, inner, unboxed, true);
12561288
}
1289+
ast::pat_region(inner) => {
1290+
let loaded_val = Load(bcx, val);
1291+
bcx = bind_irrefutable_pat(bcx, inner, loaded_val, true);
1292+
}
12571293
ast::pat_wild | ast::pat_lit(_) | ast::pat_range(_, _) => ()
12581294
}
12591295
return bcx;

src/rustdoc/extract.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export from_srv, extract, to_str, interner;
1010
* there. */
1111
macro_rules! interner_key (
1212
() => (cast::transmute::<(uint, uint),
13-
&fn(+@@syntax::parse::token::ident_interner)>((-3 as uint, 0u)))
13+
&fn(+v: @@syntax::parse::token::ident_interner)>((-3 as uint, 0u)))
1414
)
1515

1616
// Hack; rather than thread an interner through everywhere, rely on

src/rustdoc/markdown_writer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ enum WriteInstr {
1414
Done
1515
}
1616

17-
type Writer = fn~(+WriteInstr);
17+
type Writer = fn~(+v: WriteInstr);
1818
type WriterFactory = fn~(page: doc::Page) -> Writer;
1919

2020
trait WriterUtils {
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
fn foo<T>(s: &str) {
1+
fn foo(s: &~str) -> bool {
22
match s {
3-
&"kitty" => fail ~"cat",
4-
_ => ()
3+
&~"kitty" => true,
4+
_ => false
55
}
66
}
77

88
fn main() {
9-
10-
}
9+
assert foo(&~"kitty");
10+
assert !foo(&~"gata");
11+
}
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
fn foo<T>(s: &r/uint) {
1+
fn foo(s: &r/uint) -> bool {
22
match s {
3-
&3 => fail ~"oh",
4-
_ => ()
3+
&3 => true,
4+
_ => false
55
}
66
}
77

88
fn main() {
9-
10-
}
9+
assert foo(&3);
10+
assert !foo(&4);
11+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn main() {
2+
let (&x, &y, &z) = (&3, &'a', &@"No pets!");
3+
assert x == 3;
4+
assert y == 'a';
5+
assert z == @"No pets!";
6+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
fn select(x: &r/Option<int>, y: &r/Option<int>) -> &r/Option<int> {
2+
match (x, y) {
3+
(&None, &None) => x,
4+
(&Some(_), _) => x,
5+
(&None, &Some(_)) => y
6+
}
7+
}
8+
9+
fn main() {
10+
let x = None;
11+
let y = Some(3);
12+
assert select(&x, &y).get() == 3;
13+
}
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
fn foo<T>(x: &T) {
1+
fn foo<T: Copy>(x: &T) -> T{
22
match x {
3-
&a => fail #fmt("%?", a)
3+
&a => a
44
}
55
}
66

77
fn main() {
8-
9-
}
8+
assert foo(&3) == 3;
9+
assert foo(&'a') == 'a';
10+
assert foo(&@"Dogs rule, cats drool") == @"Dogs rule, cats drool";
11+
}

0 commit comments

Comments
 (0)