about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-09-07 17:07:32 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-09-07 17:09:07 -0700
commit53ce42dc4f4fceaf6881a3026f3dbc8fd81ae626 (patch)
treefe06630b44b10afc5708cbebdacb9f8471580ab3 /src
parente9f5a099dfcb42c7f2bb38974b57bbde7042ee9c (diff)
downloadrust-53ce42dc4f4fceaf6881a3026f3dbc8fd81ae626.tar.gz
rust-53ce42dc4f4fceaf6881a3026f3dbc8fd81ae626.zip
Implement &-patterns
Closes #2855
Diffstat (limited to 'src')
-rw-r--r--src/libsyntax/ast.rs1
-rw-r--r--src/libsyntax/ast_util.rs2
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/parse/parser.rs23
-rw-r--r--src/libsyntax/print/pprust.rs4
-rw-r--r--src/libsyntax/visit.rs3
-rw-r--r--src/rustc/middle/check_alt.rs14
-rw-r--r--src/rustc/middle/mem_categorization.rs5
-rw-r--r--src/rustc/middle/trans/alt.rs8
-rw-r--r--src/rustc/middle/typeck/check/alt.rs16
-rw-r--r--src/test/run-pass/borrowed-ptr-pattern-2.rs10
-rw-r--r--src/test/run-pass/borrowed-ptr-pattern-3.rs10
-rw-r--r--src/test/run-pass/borrowed-ptr-pattern.rs9
13 files changed, 88 insertions, 18 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 03106f97bc7..b1f54e701ac 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -360,6 +360,7 @@ enum pat_ {
     pat_tup(~[@pat]),
     pat_box(@pat),
     pat_uniq(@pat),
+    pat_region(@pat), // borrowed pointer pattern
     pat_lit(@expr),
     pat_range(@expr, @expr),
 }
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 1ff4728f472..429028b966e 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -595,7 +595,7 @@ fn walk_pat(pat: @pat, it: fn(@pat)) {
       pat_enum(_, Some(s)) | pat_tup(s) => for s.each |p| {
         walk_pat(p, it)
       },
-      pat_box(s) | pat_uniq(s) => walk_pat(s, it),
+      pat_box(s) | pat_uniq(s) | pat_region(s) => walk_pat(s, it),
       pat_wild | pat_lit(_) | pat_range(_, _) | pat_ident(_, _, _)
         | pat_enum(_, _) => ()
     }
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 976a57a919c..c7ce86921f6 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -384,6 +384,7 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ {
           pat_tup(elts) => pat_tup(vec::map(elts, |x| fld.fold_pat(x))),
           pat_box(inner) => pat_box(fld.fold_pat(inner)),
           pat_uniq(inner) => pat_uniq(fld.fold_pat(inner)),
+          pat_region(inner) => pat_region(fld.fold_pat(inner)),
           pat_range(e1, e2) => {
             pat_range(fld.fold_expr(e1), fld.fold_expr(e2))
           }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 175247bfaf3..a21d9de7567 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -42,8 +42,8 @@ use ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
              mac_invoc_tt, mac_var, matcher, match_nonterminal, match_seq,
              match_tok, method, mode, module_ns, mt, mul, mutability,
              named_field, neg, noreturn, not, pat, pat_box, pat_enum,
-             pat_ident, pat_lit, pat_range, pat_rec, pat_struct, pat_tup,
-             pat_uniq, pat_wild, path, private, proto, proto_bare,
+             pat_ident, pat_lit, pat_range, pat_rec, pat_region, pat_struct,
+             pat_tup, pat_uniq, pat_wild, path, private, proto, proto_bare,
              proto_block, proto_box, proto_uniq, provided, public, pure_fn,
              purity, re_anon, re_named, region, rem, required, ret_style,
              return_val, self_ty, shl, shr, stmt, stmt_decl, stmt_expr,
@@ -1844,6 +1844,25 @@ struct parser {
             };
 
           }
+          token::BINOP(token::AND) => {
+              let lo = self.span.lo;
+              self.bump();
+              let sub = self.parse_pat(refutable);
+              hi = sub.span.hi;
+              // HACK: parse &"..." as a literal of a borrowed str
+              pat = match sub.node {
+                  pat_lit(e@@{
+                      node: expr_lit(@{node: lit_str(_), span: _}), _
+                  }) => {
+                      let vst = @{id: self.get_id(), callee_id: self.get_id(),
+                                  node: expr_vstore(e, 
+                                          vstore_slice(self.region_from_name(None))),
+                                  span: mk_sp(lo, hi)};
+                      pat_lit(vst)
+                  }
+              _ => pat_region(sub)
+              };
+          }
           token::LBRACE => {
             self.bump();
             let (fields, etc) = self.parse_pat_fields(refutable);
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 8b17760c7f2..451d5be1a50 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1537,6 +1537,10 @@ fn print_pat(s: ps, &&pat: @ast::pat) {
       }
       ast::pat_box(inner) => { word(s.s, ~"@"); print_pat(s, inner); }
       ast::pat_uniq(inner) => { word(s.s, ~"~"); print_pat(s, inner); }
+      ast::pat_region(inner) => {
+          word(s.s, ~"&");
+          print_pat(s, inner);
+      }
       ast::pat_lit(e) => print_expr(s, e),
       ast::pat_range(begin, end) => {
         print_expr(s, begin);
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 410108bb8ce..ffe97197f6f 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -237,7 +237,8 @@ fn visit_pat<E>(p: @pat, e: E, v: vt<E>) {
       pat_tup(elts) => for elts.each |elt| {
         v.visit_pat(elt, e, v)
       },
-      pat_box(inner) | pat_uniq(inner) => v.visit_pat(inner, e, v),
+      pat_box(inner) | pat_uniq(inner) | pat_region(inner) =>
+          v.visit_pat(inner, e, v),
       pat_ident(_, path, inner) => {
           visit_path(path, e, v);
           do option::iter(inner) |subpat| { v.visit_pat(subpat, e, v)};
diff --git a/src/rustc/middle/check_alt.rs b/src/rustc/middle/check_alt.rs
index 364cd4890ab..b4a5db2baa4 100644
--- a/src/rustc/middle/check_alt.rs
+++ b/src/rustc/middle/check_alt.rs
@@ -235,7 +235,7 @@ fn pat_ctor_id(tcx: ty::ctxt, p: @pat) -> Option<ctor> {
       pat_range(lo, hi) => {
         Some(range(eval_const_expr(tcx, lo), eval_const_expr(tcx, hi)))
       }
-      pat_box(_) | pat_uniq(_) | pat_rec(_, _) | pat_tup(_) |
+      pat_box(_) | pat_uniq(_) | pat_rec(_, _) | pat_tup(_) | pat_region(*) |
       pat_struct(*) => {
         Some(single)
       }
@@ -258,8 +258,8 @@ fn is_wild(tcx: ty::ctxt, p: @pat) -> bool {
 
 fn missing_ctor(tcx: ty::ctxt, m: matrix, left_ty: ty::t) -> Option<ctor> {
     match ty::get(left_ty).struct {
-      ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_tup(_) | ty::ty_rec(_) |
-      ty::ty_class(*) => {
+      ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) | ty::ty_tup(_) |
+      ty::ty_rec(_) | ty::ty_class(*) => {
         for m.each |r| {
             if !is_wild(tcx, r[0]) { return None; }
         }
@@ -305,7 +305,7 @@ fn ctor_arity(tcx: ty::ctxt, ctor: ctor, ty: ty::t) -> uint {
     match ty::get(ty).struct {
       ty::ty_tup(fs) => fs.len(),
       ty::ty_rec(fs) => fs.len(),
-      ty::ty_box(_) | ty::ty_uniq(_) => 1u,
+      ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) => 1u,
       ty::ty_enum(eid, _) => {
           let id = match ctor { variant(id) => id,
           _ => fail ~"impossible case" };
@@ -386,7 +386,8 @@ fn specialize(tcx: ty::ctxt, r: ~[@pat], ctor_id: ctor, arity: uint,
         Some(vec::append(args, vec::tail(r)))
       }
       pat_tup(args) => Some(vec::append(args, vec::tail(r))),
-      pat_box(a) | pat_uniq(a) => Some(vec::append(~[a], vec::tail(r))),
+      pat_box(a) | pat_uniq(a) | pat_region(a) =>
+          Some(vec::append(~[a], vec::tail(r))),
       pat_lit(expr) => {
         let e_v = eval_const_expr(tcx, expr);
         let match_ = match ctor_id {
@@ -440,7 +441,8 @@ fn is_refutable(tcx: ty::ctxt, pat: @pat) -> bool {
     }
 
     match pat.node {
-      pat_box(sub) | pat_uniq(sub) | pat_ident(_, _, Some(sub)) => {
+      pat_box(sub) | pat_uniq(sub) | pat_region(sub) |
+      pat_ident(_, _, Some(sub)) => {
         is_refutable(tcx, sub)
       }
       pat_wild | pat_ident(_, _, None) => { false }
diff --git a/src/rustc/middle/mem_categorization.rs b/src/rustc/middle/mem_categorization.rs
index 7440d37ae5d..75868e6300f 100644
--- a/src/rustc/middle/mem_categorization.rs
+++ b/src/rustc/middle/mem_categorization.rs
@@ -898,8 +898,9 @@ impl &mem_categorization_ctxt {
             }
           }
 
-          ast::pat_box(subpat) | ast::pat_uniq(subpat) => {
-            // @p1, ~p1
+          ast::pat_box(subpat) | ast::pat_uniq(subpat) |
+          ast::pat_region(subpat) => {
+            // @p1, ~p1, &p1
             match self.cat_deref(subpat, cmt, 0u, true) {
               Some(subcmt) => {
                 self.cat_pattern(subcmt, subpat, op);
diff --git a/src/rustc/middle/trans/alt.rs b/src/rustc/middle/trans/alt.rs
index fb7c8fae337..e09f9860b58 100644
--- a/src/rustc/middle/trans/alt.rs
+++ b/src/rustc/middle/trans/alt.rs
@@ -914,12 +914,8 @@ fn bind_irrefutable_pat(bcx: block, pat: @ast::pat, val: ValueRef,
                 bcx = bind_irrefutable_pat(bcx, elem, fldptr, make_copy);
             }
         }
-        ast::pat_box(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_uniq(inner) => {
+        ast::pat_box(inner) | ast::pat_uniq(inner) |
+        ast::pat_region(inner) => {
             let llbox = Load(bcx, val);
             let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]);
             bcx = bind_irrefutable_pat(bcx, inner, unboxed, true);
diff --git a/src/rustc/middle/typeck/check/alt.rs b/src/rustc/middle/typeck/check/alt.rs
index 0282a9d78c4..2d49714d7d2 100644
--- a/src/rustc/middle/typeck/check/alt.rs
+++ b/src/rustc/middle/typeck/check/alt.rs
@@ -447,6 +447,22 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
           }
         }
       }
+      ast::pat_region(inner) => {
+        match structure_of(fcx, pat.span, expected) {
+          ty::ty_rptr(_, e_inner) => {
+            check_pat(pcx, inner, e_inner.ty);
+            fcx.write_ty(pat.id, expected);
+          }
+          _ => {
+            tcx.sess.span_fatal(
+                pat.span,
+                ~"mismatched types: expected `" +
+                fcx.infcx().ty_to_str(expected) +
+                ~"` found borrowed pointer");
+          }
+        }
+      }
+
     }
 }
 
diff --git a/src/test/run-pass/borrowed-ptr-pattern-2.rs b/src/test/run-pass/borrowed-ptr-pattern-2.rs
new file mode 100644
index 00000000000..8e31bc38e32
--- /dev/null
+++ b/src/test/run-pass/borrowed-ptr-pattern-2.rs
@@ -0,0 +1,10 @@
+fn foo<T>(s: &str) {
+    match s {
+        &"kitty" => fail ~"cat",
+        _ => ()
+    }
+}
+
+fn main() {
+
+}
\ No newline at end of file
diff --git a/src/test/run-pass/borrowed-ptr-pattern-3.rs b/src/test/run-pass/borrowed-ptr-pattern-3.rs
new file mode 100644
index 00000000000..844e36ccf3b
--- /dev/null
+++ b/src/test/run-pass/borrowed-ptr-pattern-3.rs
@@ -0,0 +1,10 @@
+fn foo<T>(s: &r/uint) {
+    match s {
+        &3 => fail ~"oh",
+        _ => ()
+    }
+}
+
+fn main() {
+
+}
\ No newline at end of file
diff --git a/src/test/run-pass/borrowed-ptr-pattern.rs b/src/test/run-pass/borrowed-ptr-pattern.rs
new file mode 100644
index 00000000000..afe1f34fac4
--- /dev/null
+++ b/src/test/run-pass/borrowed-ptr-pattern.rs
@@ -0,0 +1,9 @@
+fn foo<T>(x: &T) {
+    match x {
+        &a => fail #fmt("%?", a)
+    }
+}
+
+fn main() {
+
+}
\ No newline at end of file