]> git.lizzy.rs Git - rust.git/commitdiff
Implement &-patterns
authorTim Chevalier <chevalier@alum.wellesley.edu>
Sat, 8 Sep 2012 00:07:32 +0000 (17:07 -0700)
committerTim Chevalier <chevalier@alum.wellesley.edu>
Sat, 8 Sep 2012 00:09:07 +0000 (17:09 -0700)
Closes #2855

13 files changed:
src/libsyntax/ast.rs
src/libsyntax/ast_util.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/rustc/middle/check_alt.rs
src/rustc/middle/mem_categorization.rs
src/rustc/middle/trans/alt.rs
src/rustc/middle/typeck/check/alt.rs
src/test/run-pass/borrowed-ptr-pattern-2.rs [new file with mode: 0644]
src/test/run-pass/borrowed-ptr-pattern-3.rs [new file with mode: 0644]
src/test/run-pass/borrowed-ptr-pattern.rs [new file with mode: 0644]

index 03106f97bc74b76bd375cd756a5ac68ef45566b2..b1f54e701ac8223c9835d929b10da816b0f9f0f4 100644 (file)
@@ -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),
 }
index 1ff4728f47264e020ebc6a37da1155846690070e..429028b966ec2991c8c6a2e9babc28063cce3297 100644 (file)
@@ -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(_, _) => ()
     }
index 976a57a919c7ad48c9ed248490707a18e54f4c24..c7ce86921f62eaecb5c6dada5b41b9c675e25a5e 100644 (file)
@@ -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))
           }
index 175247bfaf3a1f876092abf99d30b25e6d2a76a2..a21d9de7567dadd7e53daf857cd643a87dce76d3 100644 (file)
@@ -42,8 +42,8 @@
              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 @@ fn parse_pat(refutable: bool) -> @pat {
             };
 
           }
+          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);
index 8b17760c7f2fc48b5829d2b4140a7bde55601c05..451d5be1a500326752da1c70e75f8e65c36d9983 100644 (file)
@@ -1537,6 +1537,10 @@ fn print_field(s: ps, f: ast::field_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);
index 410108bb8ce89f177daa6a21bb6f2844fdcf1ede..ffe97197f6f6ac0737eca4ed478b555fb8266fc8 100644 (file)
@@ -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)};
index 364cd4890ab89a2a9d5acdcb41f1adbf71b1aec9..b4a5db2baa427f3862efb941ad89c85f9a3d080d 100644 (file)
@@ -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 }
index 7440d37ae5dbd3e141831cf351271bf970d139de..75868e6300f9d985c3f57580d0d4a8cf1f316484 100644 (file)
@@ -898,8 +898,9 @@ fn cat_pattern(cmt: cmt, pat: @ast::pat, op: fn(cmt, @ast::pat)) {
             }
           }
 
-          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);
index fb7c8fae3371883c623c19b35b27cdad3b1214c7..e09f9860b58b5e38f94cc29a5c985f1fae092fa3 100644 (file)
@@ -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);
index 0282a9d78c4dfd7c20edfa38458ed2d59493cfc5..2d49714d7d2eed094652f97b8a720c22705ffc10 100644 (file)
@@ -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 (file)
index 0000000..8e31bc3
--- /dev/null
@@ -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 (file)
index 0000000..844e36c
--- /dev/null
@@ -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 (file)
index 0000000..afe1f34
--- /dev/null
@@ -0,0 +1,9 @@
+fn foo<T>(x: &T) {
+    match x {
+        &a => fail #fmt("%?", a)
+    }
+}
+
+fn main() {
+
+}
\ No newline at end of file