diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 681d6296d4ea8..bc232f1259e3b 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 9ade20c556820..0498a0f95414d 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 0000000000000..36e6edc96f996 --- /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 0000000000000..97e7582e142d9 --- /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); +}