diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 198df3090ee80..451390d0f9962 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -323,7 +323,7 @@ extern "rust-intrinsic" { /// /// `forget` is unsafe because the caller is responsible for /// ensuring the argument is deallocated already. - pub fn forget(_: T) -> (); + pub fn forget(e: T) -> (); pub fn transmute(e: T) -> U; /// Returns `true` if a type requires drop glue. diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 557e7e04ebfc5..c2255616c14b8 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -954,7 +954,7 @@ impl Parser { self.expect_or(); let inputs = self.parse_seq_to_before_or( &token::COMMA, - |p| p.parse_arg_general(false)); + |p| p.parse_arg_general(false, false)); self.expect_or(); inputs }; @@ -1021,7 +1021,7 @@ impl Parser { opt_vec::Empty }; - let (inputs, variadic) = self.parse_fn_args(false, allow_variadic); + let (inputs, variadic) = self.parse_fn_args(false, allow_variadic, false); let (ret_style, ret_ty) = self.parse_ret_ty(); let decl = P(FnDecl { inputs: inputs, @@ -1054,7 +1054,7 @@ impl Parser { let (explicit_self, d) = p.parse_fn_decl_with_self(|p| { // This is somewhat dubious; We don't want to allow argument // names to be left off if there is a definition... - p.parse_arg_general(false) + p.parse_arg_general(false, false) }); let hi = p.last_span.hi; @@ -1336,16 +1336,35 @@ impl Parser { // This version of parse arg doesn't necessarily require // identifier names. - pub fn parse_arg_general(&mut self, require_name: bool) -> Arg { + pub fn parse_arg_general(&mut self, require_name: bool, + require_ident_patterns_only: bool) -> Arg { let pat = if require_name || self.is_named_argument() { - debug!("parse_arg_general parse_pat (require_name:{:?})", - require_name); - let pat = self.parse_pat(); + debug!("parse_arg_general parse_pat (require_name:{:?}) + ident_patterns_only (require_ident_patterns_only:{:?}", + require_name, + require_ident_patterns_only); + + let pat = if require_ident_patterns_only { + // issue #10877 + // Only identifiers are allowed for this type of fn decl, no + // pattern matching or destructuring. + let pat_ident = PatIdent(BindByValue(MutImmutable), + self.parse_path(NoTypesAllowed).path, + None); + @ast::Pat { + id: ast::DUMMY_NODE_ID, + span: self.last_span, + node: pat_ident + } + } else { + self.parse_pat() + }; self.expect(&token::COLON); + pat } else { - debug!("parse_arg_general ident_to_pat"); + debug!("parse_arg_general ident_to_pat require_ident_patterns_only"); ast_util::ident_to_pat(ast::DUMMY_NODE_ID, self.last_span, special_idents::invalid) @@ -1362,7 +1381,7 @@ impl Parser { // parse a single function argument pub fn parse_arg(&mut self) -> Arg { - self.parse_arg_general(true) + self.parse_arg_general(true, false) } // parse an argument in a lambda header e.g. |arg, arg| @@ -3567,7 +3586,8 @@ impl Parser { (lifetimes, opt_vec::take_vec(result)) } - fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) + fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool, + require_ident_patterns_only: bool) -> (~[Arg], bool) { let sp = self.span; let mut args: ~[Option] = @@ -3589,7 +3609,7 @@ impl Parser { } None } else { - Some(p.parse_arg_general(named_args)) + Some(p.parse_arg_general(named_args, require_ident_patterns_only)) } } ); @@ -3615,9 +3635,12 @@ impl Parser { } // parse the argument list and result type of a function declaration - pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> P { + pub fn parse_fn_decl(&mut self, allow_variadic: bool, + require_ident_patterns_only: bool) -> P { - let (args, variadic) = self.parse_fn_args(true, allow_variadic); + let (args, variadic) = self.parse_fn_args(true, + allow_variadic, + require_ident_patterns_only); let (ret_style, ret_ty) = self.parse_ret_ty(); P(FnDecl { @@ -3882,7 +3905,7 @@ impl Parser { // parse an item-position function declaration. fn parse_item_fn(&mut self, purity: Purity, abis: AbiSet) -> ItemInfo { let (ident, generics) = self.parse_fn_header(); - let decl = self.parse_fn_decl(false); + let decl = self.parse_fn_decl(false, false); let (inner_attrs, body) = self.parse_inner_attrs_and_block(); (ident, ItemFn(decl, purity, abis, generics, body), Some(inner_attrs)) } @@ -4320,7 +4343,10 @@ impl Parser { } let (ident, generics) = self.parse_fn_header(); - let decl = self.parse_fn_decl(true); + // ForeignItemFn definitions args: + // First arg: + // Second arg: require_ident_patterns_only (valid fns with ident only) + let decl = self.parse_fn_decl(true, true); let hi = self.span.hi; self.expect(&token::SEMI); @ast::ForeignItem { ident: ident, diff --git a/src/test/compile-fail/extern-fn-type-only-in-ident-position.rs b/src/test/compile-fail/extern-fn-type-only-in-ident-position.rs new file mode 100644 index 0000000000000..c3b4429112f76 --- /dev/null +++ b/src/test/compile-fail/extern-fn-type-only-in-ident-position.rs @@ -0,0 +1,17 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Concerning issue #10877 + +extern { + fn external_fn_six(~int); //~ ERROR expected ident, found `~` +} + +fn main() {} diff --git a/src/test/compile-fail/extern-ignore-in-ident-position.rs b/src/test/compile-fail/extern-ignore-in-ident-position.rs new file mode 100644 index 0000000000000..800a7ee7e7721 --- /dev/null +++ b/src/test/compile-fail/extern-ignore-in-ident-position.rs @@ -0,0 +1,17 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Concerning issue #10877 + +extern { + fn external_fn_five(_: int); //~ ERROR expected ident, found `_` +} + +fn main() {} diff --git a/src/test/compile-fail/extern-literal-in-ident-position.rs b/src/test/compile-fail/extern-literal-in-ident-position.rs new file mode 100644 index 0000000000000..ab22aff3eac85 --- /dev/null +++ b/src/test/compile-fail/extern-literal-in-ident-position.rs @@ -0,0 +1,17 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Concerning issue #10877 + +extern { + fn external_fn_one(1: ()); //~ ERROR expected ident, found `1` +} + +fn main() {} diff --git a/src/test/compile-fail/extern-nil-type-in-ident-position.rs b/src/test/compile-fail/extern-nil-type-in-ident-position.rs new file mode 100644 index 0000000000000..f4ad1ba0d4384 --- /dev/null +++ b/src/test/compile-fail/extern-nil-type-in-ident-position.rs @@ -0,0 +1,17 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Concerning issue #10877 + +extern { + fn external_fn_two((): int); //~ ERROR expected ident, found `(` +} + +fn main() {} diff --git a/src/test/compile-fail/extern-struct-destr-in-ident-position.rs b/src/test/compile-fail/extern-struct-destr-in-ident-position.rs new file mode 100644 index 0000000000000..552f22e227d7a --- /dev/null +++ b/src/test/compile-fail/extern-struct-destr-in-ident-position.rs @@ -0,0 +1,19 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Concerning issue #10877 + +struct Foo { x: int } + +extern { + fn external_fn_three(Foo {x}: int); //~ ERROR expected `:` but found `{` +} + +fn main() {} diff --git a/src/test/compile-fail/extern-tuple-destr-in-ident-position.rs b/src/test/compile-fail/extern-tuple-destr-in-ident-position.rs new file mode 100644 index 0000000000000..049754cbf45b2 --- /dev/null +++ b/src/test/compile-fail/extern-tuple-destr-in-ident-position.rs @@ -0,0 +1,17 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Concerning issue #10877 + +extern { + fn external_fn_four((x,y): int); //~ ERROR expected ident, found `(` +} + +fn main() {} diff --git a/src/test/compile-fail/variadic-ffi.rs b/src/test/compile-fail/variadic-ffi.rs index 3156cd9af3276..28615641187a6 100644 --- a/src/test/compile-fail/variadic-ffi.rs +++ b/src/test/compile-fail/variadic-ffi.rs @@ -9,7 +9,7 @@ // except according to those terms. extern "stdcall" { - fn printf(_: *u8, ...); //~ ERROR: variadic function must have C calling convention + fn printf(f: *u8, ...); //~ ERROR: variadic function must have C calling convention } extern {