]> git.lizzy.rs Git - rust.git/commitdiff
Fix trans for region patterns (&P)
authorNiko Matsakis <niko@alum.mit.edu>
Sun, 23 Sep 2012 12:39:39 +0000 (05:39 -0700)
committerNiko Matsakis <niko@alum.mit.edu>
Sun, 23 Sep 2012 18:30:20 +0000 (13:30 -0500)
src/libsyntax/parse/token.rs
src/rustc/middle/trans/alt.rs
src/rustdoc/extract.rs
src/rustdoc/markdown_writer.rs
src/test/run-pass/borrowed-ptr-pattern-2.rs
src/test/run-pass/borrowed-ptr-pattern-3.rs
src/test/run-pass/borrowed-ptr-pattern-infallible.rs [new file with mode: 0644]
src/test/run-pass/borrowed-ptr-pattern-option.rs [new file with mode: 0644]
src/test/run-pass/borrowed-ptr-pattern.rs

index 9bf612c588a848041ee7e213fa6a2d2634316b41..37f2e6bd1898e3fbbcb0c7eaafd1370039709bdf 100644 (file)
@@ -331,7 +331,7 @@ mod special_idents {
  * so we have to use a unique number. See taskgroup_key! in task.rs
  * for another case of this. */
 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)))
 )
 
index c7abed19c597a7336460e4e4eec87e4edc15b996..0772711374195c466cd8168cd057cf92fe75a9b9 100644 (file)
@@ -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 add_to_set(tcx: ty::ctxt, set: &DVec<Opt>, val: Opt) {
         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 {
-    for vec::each(m) |br| {
-        match br.pats[col].node {
-          ast::pat_box(_) => return true,
-          _ => ()
-        }
+// Macro for deciding whether any of the remaining matches fit a given kind of
+// 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 {
+                $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 {
-    for vec::each(m) |br| {
-        match br.pats[col].node {
-          ast::pat_uniq(_) => return true,
-          _ => ()
-        }
-    }
-    return false;
+    any_pat!(m, ast::pat_uniq(_))
+}
+
+fn any_region_pat(m: &[@Match], col: uint) -> bool {
+    any_pat!(m, ast::pat_region(_))
 }
 
 fn any_tup_pat(m: &[@Match], col: uint) -> bool {
-    for vec::each(m) |br| {
-        match br.pats[col].node {
-          ast::pat_tup(_) => return true,
-          _ => ()
-        }
-    }
-    return false;
+    any_pat!(m, ast::pat_tup(_))
 }
 
 type mk_fail = fn@() -> BasicBlockRef;
@@ -940,6 +966,13 @@ fn compile_submatch(bcx: block,
         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
     let opts = get_options(ccx, m, col);
     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);
             }
         }
-        ast::pat_box(inner) | ast::pat_uniq(inner) |
-        ast::pat_region(inner) => {
+        ast::pat_box(inner) | ast::pat_uniq(inner) => {
             let llbox = Load(bcx, val);
             let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]);
             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(_, _) => ()
     }
     return bcx;
index 0f7728d60f09d1c1adc8bc4dae69ded1b953b3e6..b8a13b712e5867bc0d9ad1e6dd3bb97a60c97db1 100644 (file)
@@ -10,7 +10,7 @@
  * there. */
 macro_rules! interner_key (
     () => (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
index 5749e4dcb2347b764d8d37626a94c297bdc4c2b8..998492630677355ea637cf898e879d75c03be907 100644 (file)
@@ -14,7 +14,7 @@ enum WriteInstr {
     Done
 }
 
-type Writer = fn~(+WriteInstr);
+type Writer = fn~(+v: WriteInstr);
 type WriterFactory = fn~(page: doc::Page) -> Writer;
 
 trait WriterUtils {
index 8e31bc38e32599e16dd1cd884ae12f8fec4c70ab..1cfe037c729e73e9852c7344040584810cbaa2b1 100644 (file)
@@ -1,10 +1,11 @@
-fn foo<T>(s: &str) {
+fn foo(s: &~str) -> bool {
     match s {
-        &"kitty" => fail ~"cat",
-        _ => ()
+        &~"kitty" => true,
+        _ => false
     }
 }
 
 fn main() {
-
-}
\ No newline at end of file
+    assert foo(&~"kitty");
+    assert !foo(&~"gata");
+}
index 844e36ccf3bff36d53398d16c77c5e4418be672e..8d95d84966e2945b689009c8a11ebc34bfe98e95 100644 (file)
@@ -1,10 +1,11 @@
-fn foo<T>(s: &r/uint) {
+fn foo(s: &r/uint) -> bool {
     match s {
-        &3 => fail ~"oh",
-        _ => ()
+        &3 => true,
+        _ => false
     }
 }
 
 fn main() {
-
-}
\ No newline at end of file
+    assert foo(&3);
+    assert !foo(&4);
+}
diff --git a/src/test/run-pass/borrowed-ptr-pattern-infallible.rs b/src/test/run-pass/borrowed-ptr-pattern-infallible.rs
new file mode 100644 (file)
index 0000000..4b2006f
--- /dev/null
@@ -0,0 +1,6 @@
+fn main() {
+    let (&x, &y, &z) = (&3, &'a', &@"No pets!");
+    assert x == 3;
+    assert y == 'a';
+    assert z == @"No pets!";
+}
diff --git a/src/test/run-pass/borrowed-ptr-pattern-option.rs b/src/test/run-pass/borrowed-ptr-pattern-option.rs
new file mode 100644 (file)
index 0000000..9da88ff
--- /dev/null
@@ -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;
+}
\ No newline at end of file
index afe1f34fac46d4db0c2589117459cdc1fd50414d..ae1c955be695652a9f0c63dc965923e7f76050d3 100644 (file)
@@ -1,9 +1,11 @@
-fn foo<T>(x: &T) {
+fn foo<T: Copy>(x: &T) -> T{
     match x {
-        &a => fail #fmt("%?", a)
+        &a => a
     }
 }
 
 fn main() {
-
-}
\ No newline at end of file
+    assert foo(&3) == 3;
+    assert foo(&'a') == 'a';
+    assert foo(&@"Dogs rule, cats drool") == @"Dogs rule, cats drool";
+}