Fix trans for region patterns (&P)
This commit is contained in:
@@ -331,7 +331,7 @@ type ident_interner = util::interner::interner<@~str>;
|
|||||||
* so we have to use a unique number. See taskgroup_key! in task.rs
|
* so we have to use a unique number. See taskgroup_key! in task.rs
|
||||||
* for another case of this. */
|
* for another case of this. */
|
||||||
macro_rules! interner_key (
|
macro_rules! interner_key (
|
||||||
() => (cast::transmute::<(uint, uint), &fn(+@@token::ident_interner)>(
|
() => (cast::transmute::<(uint, uint), &fn(+v: @@token::ident_interner)>(
|
||||||
(-3 as uint, 0u)))
|
(-3 as uint, 0u)))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -487,6 +487,31 @@ fn enter_uniq(bcx: block, dm: DefMap, m: &[@Match/&r],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn enter_region(bcx: block, dm: DefMap, m: &[@Match/&r],
|
||||||
|
col: uint, val: ValueRef)
|
||||||
|
-> ~[@Match/&r]
|
||||||
|
{
|
||||||
|
debug!("enter_region(bcx=%s, m=%s, col=%u, val=%?)",
|
||||||
|
bcx.to_str(),
|
||||||
|
matches_to_str(bcx, m),
|
||||||
|
col,
|
||||||
|
bcx.val_str(val));
|
||||||
|
let _indenter = indenter();
|
||||||
|
|
||||||
|
let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
|
||||||
|
do enter_match(bcx, dm, m, col, val) |p| {
|
||||||
|
match p.node {
|
||||||
|
ast::pat_region(sub) => {
|
||||||
|
Some(~[sub])
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
assert_is_binding_or_wild(bcx, p);
|
||||||
|
Some(~[dummy])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_options(ccx: @crate_ctxt, m: &[@Match], col: uint) -> ~[Opt] {
|
fn get_options(ccx: @crate_ctxt, m: &[@Match], col: uint) -> ~[Opt] {
|
||||||
fn add_to_set(tcx: ty::ctxt, set: &DVec<Opt>, val: Opt) {
|
fn add_to_set(tcx: ty::ctxt, set: &DVec<Opt>, val: Opt) {
|
||||||
if set.any(|l| opt_eq(tcx, &l, &val)) {return;}
|
if set.any(|l| opt_eq(tcx, &l, &val)) {return;}
|
||||||
@@ -585,34 +610,35 @@ fn root_pats_as_necessary(bcx: block, m: &[@Match],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn any_box_pat(m: &[@Match], col: uint) -> bool {
|
// Macro for deciding whether any of the remaining matches fit a given kind of
|
||||||
for vec::each(m) |br| {
|
// pattern. Note that, because the macro is well-typed, either ALL of the
|
||||||
|
// matches should fit that sort of pattern or NONE (however, some of the
|
||||||
|
// matches may be wildcards like _ or identifiers).
|
||||||
|
macro_rules! any_pat (
|
||||||
|
($m:expr, $pattern:pat) => {
|
||||||
|
vec::any($m, |br| {
|
||||||
match br.pats[col].node {
|
match br.pats[col].node {
|
||||||
ast::pat_box(_) => return true,
|
$pattern => true,
|
||||||
_ => ()
|
_ => false
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return false;
|
)
|
||||||
|
|
||||||
|
fn any_box_pat(m: &[@Match], col: uint) -> bool {
|
||||||
|
any_pat!(m, ast::pat_box(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn any_uniq_pat(m: &[@Match], col: uint) -> bool {
|
fn any_uniq_pat(m: &[@Match], col: uint) -> bool {
|
||||||
for vec::each(m) |br| {
|
any_pat!(m, ast::pat_uniq(_))
|
||||||
match br.pats[col].node {
|
}
|
||||||
ast::pat_uniq(_) => return true,
|
|
||||||
_ => ()
|
fn any_region_pat(m: &[@Match], col: uint) -> bool {
|
||||||
}
|
any_pat!(m, ast::pat_region(_))
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn any_tup_pat(m: &[@Match], col: uint) -> bool {
|
fn any_tup_pat(m: &[@Match], col: uint) -> bool {
|
||||||
for vec::each(m) |br| {
|
any_pat!(m, ast::pat_tup(_))
|
||||||
match br.pats[col].node {
|
|
||||||
ast::pat_tup(_) => return true,
|
|
||||||
_ => ()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type mk_fail = fn@() -> BasicBlockRef;
|
type mk_fail = fn@() -> BasicBlockRef;
|
||||||
@@ -940,6 +966,13 @@ fn compile_submatch(bcx: block,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if any_region_pat(m, col) {
|
||||||
|
let loaded_val = Load(bcx, val);
|
||||||
|
compile_submatch(bcx, enter_region(bcx, dm, m, col, val),
|
||||||
|
vec::append(~[loaded_val], vals_left), chk);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Decide what kind of branch we need
|
// Decide what kind of branch we need
|
||||||
let opts = get_options(ccx, m, col);
|
let opts = get_options(ccx, m, col);
|
||||||
let mut kind = no_branch;
|
let mut kind = no_branch;
|
||||||
@@ -1248,12 +1281,15 @@ fn bind_irrefutable_pat(bcx: block, pat: @ast::pat, val: ValueRef,
|
|||||||
bcx = bind_irrefutable_pat(bcx, *elem, fldptr, make_copy);
|
bcx = bind_irrefutable_pat(bcx, *elem, fldptr, make_copy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::pat_box(inner) | ast::pat_uniq(inner) |
|
ast::pat_box(inner) | ast::pat_uniq(inner) => {
|
||||||
ast::pat_region(inner) => {
|
|
||||||
let llbox = Load(bcx, val);
|
let llbox = Load(bcx, val);
|
||||||
let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]);
|
let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]);
|
||||||
bcx = bind_irrefutable_pat(bcx, inner, unboxed, true);
|
bcx = bind_irrefutable_pat(bcx, inner, unboxed, true);
|
||||||
}
|
}
|
||||||
|
ast::pat_region(inner) => {
|
||||||
|
let loaded_val = Load(bcx, val);
|
||||||
|
bcx = bind_irrefutable_pat(bcx, inner, loaded_val, true);
|
||||||
|
}
|
||||||
ast::pat_wild | ast::pat_lit(_) | ast::pat_range(_, _) => ()
|
ast::pat_wild | ast::pat_lit(_) | ast::pat_range(_, _) => ()
|
||||||
}
|
}
|
||||||
return bcx;
|
return bcx;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export from_srv, extract, to_str, interner;
|
|||||||
* there. */
|
* there. */
|
||||||
macro_rules! interner_key (
|
macro_rules! interner_key (
|
||||||
() => (cast::transmute::<(uint, uint),
|
() => (cast::transmute::<(uint, uint),
|
||||||
&fn(+@@syntax::parse::token::ident_interner)>((-3 as uint, 0u)))
|
&fn(+v: @@syntax::parse::token::ident_interner)>((-3 as uint, 0u)))
|
||||||
)
|
)
|
||||||
|
|
||||||
// Hack; rather than thread an interner through everywhere, rely on
|
// Hack; rather than thread an interner through everywhere, rely on
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ enum WriteInstr {
|
|||||||
Done
|
Done
|
||||||
}
|
}
|
||||||
|
|
||||||
type Writer = fn~(+WriteInstr);
|
type Writer = fn~(+v: WriteInstr);
|
||||||
type WriterFactory = fn~(page: doc::Page) -> Writer;
|
type WriterFactory = fn~(page: doc::Page) -> Writer;
|
||||||
|
|
||||||
trait WriterUtils {
|
trait WriterUtils {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
fn foo<T>(s: &str) {
|
fn foo(s: &~str) -> bool {
|
||||||
match s {
|
match s {
|
||||||
&"kitty" => fail ~"cat",
|
&~"kitty" => true,
|
||||||
_ => ()
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
assert foo(&~"kitty");
|
||||||
|
assert !foo(&~"gata");
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
fn foo<T>(s: &r/uint) {
|
fn foo(s: &r/uint) -> bool {
|
||||||
match s {
|
match s {
|
||||||
&3 => fail ~"oh",
|
&3 => true,
|
||||||
_ => ()
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
assert foo(&3);
|
||||||
|
assert !foo(&4);
|
||||||
}
|
}
|
||||||
6
src/test/run-pass/borrowed-ptr-pattern-infallible.rs
Normal file
6
src/test/run-pass/borrowed-ptr-pattern-infallible.rs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
fn main() {
|
||||||
|
let (&x, &y, &z) = (&3, &'a', &@"No pets!");
|
||||||
|
assert x == 3;
|
||||||
|
assert y == 'a';
|
||||||
|
assert z == @"No pets!";
|
||||||
|
}
|
||||||
13
src/test/run-pass/borrowed-ptr-pattern-option.rs
Normal file
13
src/test/run-pass/borrowed-ptr-pattern-option.rs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
fn select(x: &r/Option<int>, y: &r/Option<int>) -> &r/Option<int> {
|
||||||
|
match (x, y) {
|
||||||
|
(&None, &None) => x,
|
||||||
|
(&Some(_), _) => x,
|
||||||
|
(&None, &Some(_)) => y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = None;
|
||||||
|
let y = Some(3);
|
||||||
|
assert select(&x, &y).get() == 3;
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
fn foo<T>(x: &T) {
|
fn foo<T: Copy>(x: &T) -> T{
|
||||||
match x {
|
match x {
|
||||||
&a => fail #fmt("%?", a)
|
&a => a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
assert foo(&3) == 3;
|
||||||
|
assert foo(&'a') == 'a';
|
||||||
|
assert foo(&@"Dogs rule, cats drool") == @"Dogs rule, cats drool";
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user