about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-11-06 18:41:06 -0800
committerPatrick Walton <pcwalton@mimiga.net>2012-11-07 19:29:30 -0800
commit0fc952372a1010bc567b1c183105e4fd3f395af0 (patch)
tree4cf44e50cf87c1a151dfc17a543710e7df5218fc /src/libsyntax
parentb223c9c4651ee2f4b8fe2af0136e657a0893caa4 (diff)
rustc: Support irrefutable patterns in function arguments. r=nmatsakis
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs6
-rw-r--r--src/libsyntax/ast_util.rs6
-rw-r--r--src/libsyntax/ext/auto_serialize.rs22
-rw-r--r--src/libsyntax/ext/base.rs17
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs9
-rw-r--r--src/libsyntax/fold.rs6
-rw-r--r--src/libsyntax/parse/parser.rs23
-rw-r--r--src/libsyntax/print/pprust.rs19
-rw-r--r--src/libsyntax/visit.rs5
9 files changed, 80 insertions, 33 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 8fcb9300b52..7452e41fac3 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -662,8 +662,8 @@ type expr = {id: node_id, callee_id: node_id, node: expr_, span: span};
 
 #[auto_serialize]
 #[auto_deserialize]
-enum log_level { error, debug, other }
-// 0 = error, 1 = debug, 2 = other
+enum log_level { error, debug, log_other }
+// 0 = error, 1 = debug, 2 = log_other
 
 #[auto_serialize]
 #[auto_deserialize]
@@ -1137,7 +1137,7 @@ impl Ty : to_bytes::IterBytes {
 
 #[auto_serialize]
 #[auto_deserialize]
-type arg = {mode: mode, ty: @Ty, ident: ident, id: node_id};
+type arg = {mode: mode, ty: @Ty, pat: @pat, id: node_id};
 
 #[auto_serialize]
 #[auto_deserialize]
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index ea49cce5047..d3b879da7dd 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -274,6 +274,12 @@ fn ident_to_path(s: span, +i: ident) -> @path {
       rp: None, types: ~[]}
 }
 
+fn ident_to_pat(id: node_id, s: span, +i: ident) -> @pat {
+    @{id: id,
+      node: pat_ident(bind_by_value, ident_to_path(s, i), None),
+      span: s}
+}
+
 pure fn is_unguarded(a: &arm) -> bool {
     match a.guard {
       None => true,
diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs
index 707787e78b9..39e94291d8b 100644
--- a/src/libsyntax/ext/auto_serialize.rs
+++ b/src/libsyntax/ext/auto_serialize.rs
@@ -515,7 +515,12 @@ fn mk_ser_method(
     let ser_inputs = ~[{
         mode: ast::infer(cx.next_id()),
         ty: ty_s,
-        ident: cx.ident_of(~"__s"),
+        pat: @{id: cx.next_id(),
+               node: ast::pat_ident(
+                    ast::bind_by_value,
+                    ast_util::ident_to_path(span, cx.ident_of(~"__s")),
+                    None),
+               span: span},
         id: cx.next_id(),
     }];
 
@@ -570,7 +575,12 @@ fn mk_deser_method(
     let deser_inputs = ~[{
         mode: ast::infer(cx.next_id()),
         ty: ty_d,
-        ident: cx.ident_of(~"__d"),
+        pat: @{id: cx.next_id(),
+               node: ast::pat_ident(
+                    ast::bind_by_value,
+                    ast_util::ident_to_path(span, cx.ident_of(~"__d")),
+                    None),
+               span: span},
         id: cx.next_id(),
     }];
 
@@ -1087,7 +1097,13 @@ fn mk_enum_deser_body(
                         node: ast::ty_infer,
                         span: span
                     },
-                    ident: cx.ident_of(~"i"),
+                    pat: @{id: cx.next_id(),
+                           node: ast::pat_ident(
+                                ast::bind_by_value,
+                                ast_util::ident_to_path(span,
+                                                        cx.ident_of(~"i")),
+                                None),
+                           span: span},
                     id: cx.next_id(),
                 }],
                 output: @{
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 5b4cc23ce09..ddf58ce0fef 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -234,24 +234,27 @@ fn mk_ctxt(parse_sess: parse::parse_sess,
     move ((move imp) as ext_ctxt)
 }
 
-fn expr_to_str(cx: ext_ctxt, expr: @ast::expr, error: ~str) -> ~str {
+fn expr_to_str(cx: ext_ctxt, expr: @ast::expr, err_msg: ~str) -> ~str {
     match expr.node {
       ast::expr_lit(l) => match l.node {
         ast::lit_str(s) => return *s,
-        _ => cx.span_fatal(l.span, error)
+        _ => cx.span_fatal(l.span, err_msg)
       },
-      _ => cx.span_fatal(expr.span, error)
+      _ => cx.span_fatal(expr.span, err_msg)
     }
 }
 
-fn expr_to_ident(cx: ext_ctxt, expr: @ast::expr, error: ~str) -> ast::ident {
+fn expr_to_ident(cx: ext_ctxt,
+                 expr: @ast::expr,
+                 err_msg: ~str) -> ast::ident {
     match expr.node {
       ast::expr_path(p) => {
         if vec::len(p.types) > 0u || vec::len(p.idents) != 1u {
-            cx.span_fatal(expr.span, error);
-        } else { return p.idents[0]; }
+            cx.span_fatal(expr.span, err_msg);
+        }
+        return p.idents[0];
       }
-      _ => cx.span_fatal(expr.span, error)
+      _ => cx.span_fatal(expr.span, err_msg)
     }
 }
 
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index 632b3b93af9..f03adb90f0b 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -4,7 +4,7 @@
 // something smarter.
 
 use ast::{ident, node_id};
-use ast_util::respan;
+use ast_util::{ident_to_path, respan};
 use codemap::span;
 use ext::base::mk_ctxt;
 
@@ -178,7 +178,12 @@ impl ext_ctxt: ext_ctxt_ast_builder {
     fn arg(name: ident, ty: @ast::Ty) -> ast::arg {
         {mode: ast::infer(self.next_id()),
          ty: ty,
-         ident: name,
+         pat: @{id: self.next_id(),
+                node: ast::pat_ident(
+                    ast::bind_by_value,
+                    ast_util::ident_to_path(self.empty_span(), name),
+                    None),
+                span: self.empty_span()},
          id: self.next_id()}
     }
 
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 3879e70cb28..8609124126c 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -105,9 +105,9 @@ fn fold_attribute_(at: attribute, fld: ast_fold) ->
 //used in noop_fold_foreign_item and noop_fold_fn_decl
 fn fold_arg_(a: arg, fld: ast_fold) -> arg {
     return {mode: a.mode,
-         ty: fld.fold_ty(a.ty),
-         ident: fld.fold_ident(a.ident),
-         id: fld.new_id(a.id)};
+            ty: fld.fold_ty(a.ty),
+            pat: fld.fold_pat(a.pat),
+            id: fld.new_id(a.id)};
 }
 //used in noop_fold_expr, and possibly elsewhere in the future
 fn fold_mac_(m: mac, fld: ast_fold) -> mac {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index db3f6abbf7b..2b42dcc0ed0 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -696,19 +696,21 @@ impl Parser {
     // identifier names.
     fn parse_arg_general(require_name: bool) -> arg {
         let mut m;
-        let i = if require_name || self.is_named_argument() {
+        let pat = if require_name || self.is_named_argument() {
             m = self.parse_arg_mode();
-            let name = self.parse_value_ident();
+            let pat = self.parse_pat(false);
             self.expect(token::COLON);
-            name
+            pat
         } else {
             m = infer(self.get_id());
-            special_idents::invalid
+            ast_util::ident_to_pat(self.get_id(),
+                                   copy self.last_span,
+                                   special_idents::invalid)
         };
 
         let t = self.parse_ty(false);
 
-        {mode: m, ty: t, ident: i, id: self.get_id()}
+        {mode: m, ty: t, pat: pat, id: self.get_id()}
     }
 
     fn parse_arg() -> arg_or_capture_item {
@@ -722,7 +724,7 @@ impl Parser {
     fn parse_fn_block_arg() -> arg_or_capture_item {
         do self.parse_capture_item_or |p| {
             let m = p.parse_arg_mode();
-            let i = p.parse_value_ident();
+            let pat = p.parse_pat(false);
             let t = if p.eat(token::COLON) {
                 p.parse_ty(false)
             } else {
@@ -730,7 +732,7 @@ impl Parser {
                   node: ty_infer,
                   span: mk_sp(p.span.lo, p.span.hi)}
             };
-            either::Left({mode: m, ty: t, ident: i, id: p.get_id()})
+            either::Left({mode: m, ty: t, pat: pat, id: p.get_id()})
         }
     }
 
@@ -1042,7 +1044,7 @@ impl Parser {
             let lvl = self.parse_expr();
             self.expect(token::COMMA);
             let e = self.parse_expr();
-            ex = expr_log(ast::other, lvl, e);
+            ex = expr_log(ast::log_other, lvl, e);
             hi = self.span.hi;
             self.expect(token::RPAREN);
         } else if self.eat_keyword(~"assert") {
@@ -2708,6 +2710,11 @@ impl Parser {
          }
     }
 
+    fn ident_to_path(i: ident) -> @path {
+        @{span: self.last_span, global: false, idents: ~[i],
+          rp: None, types: ~[]}
+    }
+
     fn parse_trait_ref() -> @trait_ref {
         @{path: self.parse_path_with_tps(false),
           ref_id: self.get_id(), impl_id: self.get_id()}
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index ed64d02cea3..0418f6776de 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1386,7 +1386,7 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
         match lvl {
           ast::debug => { word_nbsp(s, ~"log"); print_expr(s, expr); }
           ast::error => { word_nbsp(s, ~"log_err"); print_expr(s, expr); }
-          ast::other => {
+          ast::log_other => {
             word_nbsp(s, ~"log");
             popen(s);
             print_expr(s, lexp);
@@ -1820,12 +1820,19 @@ fn print_arg(s: ps, input: ast::arg) {
     ibox(s, indent_unit);
     print_arg_mode(s, input.mode);
     match input.ty.node {
-      ast::ty_infer => print_ident(s, input.ident),
+      ast::ty_infer => print_pat(s, input.pat),
       _ => {
-        if input.ident != parse::token::special_idents::invalid {
-            print_ident(s, input.ident);
-            word(s.s, ~":");
-            space(s.s);
+        match input.pat.node {
+            ast::pat_ident(_, path, _) if
+                path.idents.len() == 1 &&
+                path.idents[0] == parse::token::special_idents::invalid => {
+                // Do nothing.
+            }
+            _ => {
+                print_pat(s, input.pat);
+                word(s.s, ~":");
+                space(s.s);
+            }
         }
         print_type(s, input.ty);
       }
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 97cc52bd35a..42b869b6c34 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -277,7 +277,10 @@ fn visit_ty_params<E>(tps: ~[ty_param], e: E, v: vt<E>) {
 }
 
 fn visit_fn_decl<E>(fd: fn_decl, e: E, v: vt<E>) {
-    for fd.inputs.each |a| { v.visit_ty(a.ty, e, v); }
+    for fd.inputs.each |a| {
+        v.visit_pat(a.pat, e, v);
+        v.visit_ty(a.ty, e, v);
+    }
     v.visit_ty(fd.output, e, v);
 }