about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libsyntax/parse/parser.rs45
-rw-r--r--src/rustc/util/ppaux.rs2
-rw-r--r--src/test/compile-fail/unnamed_argument_mode.rs14
-rw-r--r--src/test/run-pass/unnamed_argument_mode.rs11
4 files changed, 54 insertions, 18 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 681d6296d4e..bc232f1259e 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -584,6 +584,29 @@ impl parser {
         } else { infer(self.get_id()) }
     }
 
+    fn is_named_argument() -> bool {
+        let offset = if self.token == token::BINOP(token::AND) {
+            1
+        } else if self.token == token::BINOP(token::MINUS) {
+            1
+        } else if self.token == token::ANDAND {
+            1
+        } else if self.token == token::BINOP(token::PLUS) {
+            if self.look_ahead(1) == token::BINOP(token::PLUS) {
+                2
+            } else {
+                1
+            }
+        } else { 0 };
+        if offset == 0 {
+            is_plain_ident(self.token)
+                && self.look_ahead(1) == token::COLON
+        } else {
+            is_plain_ident(self.look_ahead(offset))
+                && self.look_ahead(offset + 1) == token::COLON
+        }
+    }
+
     fn parse_capture_item_or(parse_arg_fn: fn(parser) -> arg_or_capture_item)
         -> arg_or_capture_item {
 
@@ -605,29 +628,17 @@ impl parser {
     // This version of parse arg doesn't necessarily require
     // identifier names.
     fn parse_arg_general(require_name: bool) -> arg {
-        let m = self.parse_arg_mode();
-        let i = if require_name {
+        let mut m;
+        let i = if require_name || self.is_named_argument() {
+            m = self.parse_arg_mode();
             let name = self.parse_value_ident();
             self.expect(token::COLON);
             name
         } else {
-            if is_plain_ident(self.token)
-                && self.look_ahead(1u) == token::COLON {
-                let name = self.parse_value_ident();
-                self.bump();
-                name
-            } else { special_idents::invalid }
+            m = infer(self.get_id());
+            special_idents::invalid
         };
 
-        match m {
-            expl(_) => {
-                if i == special_idents::invalid {
-                    self.obsolete(copy self.span, ObsoleteModeInFnType);
-                }
-            }
-            _ => {}
-        }
-
         let t = self.parse_ty(false);
 
         {mode: m, ty: t, ident: i, id: self.get_id()}
diff --git a/src/rustc/util/ppaux.rs b/src/rustc/util/ppaux.rs
index 9ade20c5568..0498a0f9541 100644
--- a/src/rustc/util/ppaux.rs
+++ b/src/rustc/util/ppaux.rs
@@ -261,7 +261,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str {
                 m == ty::default_arg_mode_for_ty(cx, ty) {
                 ~""
             } else {
-                mode_to_str(ast::expl(m))
+                mode_to_str(ast::expl(m)) + ":"
             }
           }
         };
diff --git a/src/test/compile-fail/unnamed_argument_mode.rs b/src/test/compile-fail/unnamed_argument_mode.rs
new file mode 100644
index 00000000000..36e6edc96f9
--- /dev/null
+++ b/src/test/compile-fail/unnamed_argument_mode.rs
@@ -0,0 +1,14 @@
+//error-pattern: mismatched types
+
+fn bad(&a: int) {
+}
+
+// unnamed argument &int is now parsed x: &int
+// it's not parsed &x: int anymore
+
+fn called(f: fn(&int)) {
+}
+
+fn main() {
+called(bad);
+}
diff --git a/src/test/run-pass/unnamed_argument_mode.rs b/src/test/run-pass/unnamed_argument_mode.rs
new file mode 100644
index 00000000000..97e7582e142
--- /dev/null
+++ b/src/test/run-pass/unnamed_argument_mode.rs
@@ -0,0 +1,11 @@
+fn good(a: &int) {
+}
+
+// unnamed argument &int is now parse x: &int
+
+fn called(f: fn(&int)) {
+}
+
+fn main() {
+called(good);
+}