about summary refs log tree commit diff
path: root/src/comp/syntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/comp/syntax')
-rw-r--r--src/comp/syntax/ast.rs2
-rw-r--r--src/comp/syntax/ast_util.rs5
-rw-r--r--src/comp/syntax/fold.rs4
-rw-r--r--src/comp/syntax/parse/parser.rs11
-rw-r--r--src/comp/syntax/print/pprust.rs8
-rw-r--r--src/comp/syntax/visit.rs5
6 files changed, 23 insertions, 12 deletions
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs
index be3bf5b5ee0..30acee6dc68 100644
--- a/src/comp/syntax/ast.rs
+++ b/src/comp/syntax/ast.rs
@@ -92,7 +92,7 @@ type field_pat = {ident: ident, pat: @pat};
 
 tag pat_ {
     pat_wild;
-    pat_bind(ident);
+    pat_bind(ident, option::t<@pat>);
     pat_tag(@path, [@pat]);
     pat_rec([field_pat], bool);
     pat_tup([@pat]);
diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs
index dc1d0e0bbbb..794d4bf5339 100644
--- a/src/comp/syntax/ast_util.rs
+++ b/src/comp/syntax/ast_util.rs
@@ -58,7 +58,7 @@ type pat_id_map = std::map::hashmap<str, node_id>;
 fn pat_id_map(pat: @pat) -> pat_id_map {
     let map = std::map::new_str_hash::<node_id>();
     pat_bindings(pat) {|bound|
-        let name = alt bound.node { pat_bind(n) { n } };
+        let name = alt bound.node { pat_bind(n, _) { n } };
         map.insert(name, bound.id);
     };
     ret map;
@@ -67,7 +67,8 @@ fn pat_id_map(pat: @pat) -> pat_id_map {
 // FIXME: could return a constrained type
 fn pat_bindings(pat: @pat, it: block(@pat)) {
     alt pat.node {
-      pat_bind(_) { it(pat); }
+      pat_bind(_, option::none.) { it(pat); }
+      pat_bind(_, option::some(sub)) { it(pat); pat_bindings(sub, it); }
       pat_tag(_, sub) { for p in sub { pat_bindings(p, it); } }
       pat_rec(fields, _) { for f in fields { pat_bindings(f.pat, it); } }
       pat_tup(elts) { for elt in elts { pat_bindings(elt, it); } }
diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs
index 0e76e9a15d1..ce82c4d7c3b 100644
--- a/src/comp/syntax/fold.rs
+++ b/src/comp/syntax/fold.rs
@@ -270,7 +270,9 @@ fn noop_fold_arm(a: arm, fld: ast_fold) -> arm {
 fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ {
     ret alt p {
           pat_wild. { p }
-          pat_bind(ident) { pat_bind(fld.fold_ident(ident)) }
+          pat_bind(ident, sub) {
+            pat_bind(fld.fold_ident(ident), option::map(fld.fold_pat, sub))
+          }
           pat_lit(_) { p }
           pat_tag(pth, pats) {
             pat_tag(fld.fold_path(pth), vec::map(fld.fold_pat, pats))
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index 2bf7865bf81..5748637fde4 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -1429,10 +1429,9 @@ fn parse_pat(p: parser) -> @ast::pat {
                 if p.get_bad_expr_words().contains_key(fieldname) {
                     p.fatal("found " + fieldname + " in binding position");
                 }
-                subpat =
-                    @{id: p.get_id(),
-                      node: ast::pat_bind(fieldname),
-                      span: ast_util::mk_sp(lo, hi)};
+                subpat = @{id: p.get_id(),
+                           node: ast::pat_bind(fieldname, none),
+                           span: ast_util::mk_sp(lo, hi)};
             }
             fields += [{ident: fieldname, pat: subpat}];
         }
@@ -1479,7 +1478,9 @@ fn parse_pat(p: parser) -> @ast::pat {
                         _ { true }
                       } {
             hi = p.get_hi_pos();
-            pat = ast::pat_bind(parse_value_ident(p));
+            let name = parse_value_ident(p);
+            let sub = eat(p, token::AT) ? some(parse_pat(p)) : none;
+            pat = ast::pat_bind(name, sub);
         } else {
             let tag_path = parse_path_and_ty_param_substs(p);
             hi = tag_path.span.hi;
diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs
index 2bb8463e2b9..ff28edd057a 100644
--- a/src/comp/syntax/print/pprust.rs
+++ b/src/comp/syntax/print/pprust.rs
@@ -1062,7 +1062,13 @@ fn print_pat(s: ps, &&pat: @ast::pat) {
     s.ann.pre(ann_node);
     alt pat.node {
       ast::pat_wild. { word(s.s, "_"); }
-      ast::pat_bind(id) { word(s.s, id); }
+      ast::pat_bind(id, sub) {
+        word(s.s, id);
+        alt sub {
+          some(p) { word(s.s, "@"); print_pat(s, p); }
+          _ {}
+        }
+      }
       ast::pat_tag(path, args) {
         print_path(s, path, true);
         if vec::len(args) > 0u {
diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs
index be4dbef294b..9e61d82287c 100644
--- a/src/comp/syntax/visit.rs
+++ b/src/comp/syntax/visit.rs
@@ -159,8 +159,9 @@ fn visit_pat<E>(p: @pat, e: E, v: vt<E>) {
         for f: field_pat in fields { v.visit_pat(f.pat, e, v); }
       }
       pat_tup(elts) { for elt in elts { v.visit_pat(elt, e, v); } }
-      pat_box(inner) { v.visit_pat(inner, e, v); }
-      pat_uniq(inner) { v.visit_pat(inner, e, v); }
+      pat_box(inner) | pat_uniq(inner) | pat_bind(_, some(inner)) {
+        v.visit_pat(inner, e, v);
+      }
       _ { }
     }
 }