diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 2f7d8f0984e6f..f7af135bc7605 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -31,6 +31,7 @@ //! in the HIR, especially for multiple identifiers. use dep_graph::DepGraph; +use errors::Applicability; use hir::{self, ParamName}; use hir::HirVec; use hir::map::{DefKey, DefPathData, Definitions}; @@ -1806,7 +1807,7 @@ impl<'a> LoweringContext<'a> { explicit_owner: Option, ) -> hir::PathSegment { let (mut generic_args, infer_types) = if let Some(ref generic_args) = segment.args { - let msg = "parenthesized parameters may only be used with a trait"; + let msg = "parenthesized type parameters may only be used with a `Fn` trait"; match **generic_args { GenericArgs::AngleBracketed(ref data) => { self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) @@ -1823,10 +1824,25 @@ impl<'a> LoweringContext<'a> { (hir::GenericArgs::none(), true) } ParenthesizedGenericArgs::Err => { - struct_span_err!(self.sess, data.span, E0214, "{}", msg) - .span_label(data.span, "only traits may use parentheses") - .emit(); - (hir::GenericArgs::none(), true) + let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg); + err.span_label(data.span, "only `Fn` traits may use parentheses"); + if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) { + // Do not suggest going from `Trait()` to `Trait<>` + if data.inputs.len() > 0 { + err.span_suggestion_with_applicability( + data.span, + "use angle brackets instead", + format!("<{}>", &snippet[1..snippet.len() - 1]), + Applicability::MaybeIncorrect, + ); + } + }; + err.emit(); + (self.lower_angle_bracketed_parameter_data( + &data.as_angle_bracketed_args(), + param_mode, + itctx).0, + false) } }, } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index bbcaaacbab523..d57f9247c0520 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -192,6 +192,16 @@ pub struct ParenthesisedArgs { pub output: Option>, } +impl ParenthesisedArgs { + pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs { + AngleBracketedArgs { + span: self.span, + args: self.inputs.iter().cloned().map(|input| GenericArg::Type(input)).collect(), + bindings: vec![], + } + } +} + // hack to ensure that we don't try to access the private parts of `NodeId` in this module mod node_id_inner { use rustc_data_structures::indexed_vec::Idx; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7e15b23127655..e09b7a9dd7b7f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2176,11 +2176,11 @@ impl<'a> Parser<'a> { style != PathStyle::Mod && self.check(&token::ModSep) && self.look_ahead(1, |t| is_args_start(t)) { // Generic arguments are found - `<`, `(`, `::<` or `::(`. - let lo = self.span; if self.eat(&token::ModSep) && style == PathStyle::Type && enable_warning { self.diagnostic().struct_span_warn(self.prev_span, "unnecessary path disambiguator") .span_label(self.prev_span, "try removing `::`").emit(); } + let lo = self.span; let args = if self.eat_lt() { // `<'a, T, A = U>` diff --git a/src/test/ui/error-codes/E0214.stderr b/src/test/ui/error-codes/E0214.stderr index 08a98b1c3bf3d..a10f2c00578c6 100644 --- a/src/test/ui/error-codes/E0214.stderr +++ b/src/test/ui/error-codes/E0214.stderr @@ -1,8 +1,11 @@ -error[E0214]: parenthesized parameters may only be used with a trait +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/E0214.rs:2:15 | LL | let v: Vec(&str) = vec!["foo"]; - | ^^^^^^ only traits may use parentheses + | ^^^^^^ + | | + | only `Fn` traits may use parentheses + | help: use angle brackets instead: `<&str>` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23589.rs b/src/test/ui/issues/issue-23589.rs index a59710a1a3cde..1c640af8d02b9 100644 --- a/src/test/ui/issues/issue-23589.rs +++ b/src/test/ui/issues/issue-23589.rs @@ -1,4 +1,5 @@ fn main() { let v: Vec(&str) = vec!['1', '2']; - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait + //~| ERROR mismatched types } diff --git a/src/test/ui/issues/issue-23589.stderr b/src/test/ui/issues/issue-23589.stderr index e6e07c167f349..bc2007ba39cc6 100644 --- a/src/test/ui/issues/issue-23589.stderr +++ b/src/test/ui/issues/issue-23589.stderr @@ -1,9 +1,22 @@ -error[E0214]: parenthesized parameters may only be used with a trait +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-23589.rs:2:15 | LL | let v: Vec(&str) = vec!['1', '2']; - | ^^^^^^ only traits may use parentheses + | ^^^^^^ + | | + | only `Fn` traits may use parentheses + | help: use angle brackets instead: `<&str>` -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/issue-23589.rs:2:29 + | +LL | let v: Vec(&str) = vec!['1', '2']; + | ^^^ expected &str, found char + | + = note: expected type `&str` + found type `char` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0214`. +Some errors occurred: E0214, E0308. +For more information about an error, try `rustc --explain E0214`. diff --git a/src/test/ui/issues/issue-32995-2.rs b/src/test/ui/issues/issue-32995-2.rs index a4e333ec20ae0..2234f68f24629 100644 --- a/src/test/ui/issues/issue-32995-2.rs +++ b/src/test/ui/issues/issue-32995-2.rs @@ -2,11 +2,11 @@ fn main() { { fn f() {} } - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted { fn f() -> impl ::std::marker()::Send { } } - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted } @@ -14,5 +14,5 @@ fn main() { struct X; impl ::std::marker()::Copy for X {} -//~^ ERROR parenthesized parameters may only be used with a trait +//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted diff --git a/src/test/ui/issues/issue-32995-2.stderr b/src/test/ui/issues/issue-32995-2.stderr index 0ac12b78d3842..104b76cba2df9 100644 --- a/src/test/ui/issues/issue-32995-2.stderr +++ b/src/test/ui/issues/issue-32995-2.stderr @@ -1,4 +1,4 @@ -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995-2.rs:4:28 | LL | { fn f() {} } @@ -8,7 +8,7 @@ LL | { fn f() {} } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995-2.rs:8:35 | LL | { fn f() -> impl ::std::marker()::Send { } } @@ -17,7 +17,7 @@ LL | { fn f() -> impl ::std::marker()::Send { } } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995-2.rs:16:19 | LL | impl ::std::marker()::Copy for X {} diff --git a/src/test/ui/issues/issue-32995.rs b/src/test/ui/issues/issue-32995.rs index 726cc85d3f479..c32fb63f1e584 100644 --- a/src/test/ui/issues/issue-32995.rs +++ b/src/test/ui/issues/issue-32995.rs @@ -2,32 +2,32 @@ fn main() { let x: usize() = 1; - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted let b: ::std::boxed()::Box<_> = Box::new(1); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted let p = ::std::str::()::from_utf8(b"foo").unwrap(); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted let p = ::std::str::from_utf8::()(b"foo").unwrap(); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted let o : Box<::std::marker()::Send> = Box::new(1); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted let o : Box = Box::new(1); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted } fn foo() { let d : X() = Default::default(); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted } diff --git a/src/test/ui/issues/issue-32995.stderr b/src/test/ui/issues/issue-32995.stderr index 12551bb7f1f00..97b4b7fa76ca8 100644 --- a/src/test/ui/issues/issue-32995.stderr +++ b/src/test/ui/issues/issue-32995.stderr @@ -1,4 +1,4 @@ -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995.rs:4:17 | LL | let x: usize() = 1; @@ -8,7 +8,7 @@ LL | let x: usize() = 1; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995.rs:8:24 | LL | let b: ::std::boxed()::Box<_> = Box::new(1); @@ -17,25 +17,25 @@ LL | let b: ::std::boxed()::Box<_> = Box::new(1); = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait - --> $DIR/issue-32995.rs:12:23 +error: parenthesized type parameters may only be used with a `Fn` trait + --> $DIR/issue-32995.rs:12:25 | LL | let p = ::std::str::()::from_utf8(b"foo").unwrap(); - | ^^^^ + | ^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait - --> $DIR/issue-32995.rs:16:34 +error: parenthesized type parameters may only be used with a `Fn` trait + --> $DIR/issue-32995.rs:16:36 | LL | let p = ::std::str::from_utf8::()(b"foo").unwrap(); - | ^^^^ + | ^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995.rs:20:30 | LL | let o : Box<::std::marker()::Send> = Box::new(1); @@ -44,7 +44,7 @@ LL | let o : Box<::std::marker()::Send> = Box::new(1); = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995.rs:24:37 | LL | let o : Box = Box::new(1); @@ -53,7 +53,7 @@ LL | let o : Box = Box::new(1); = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995.rs:30:14 | LL | let d : X() = Default::default(); diff --git a/src/test/ui/parser/type-parameters-in-field-exprs.stderr b/src/test/ui/parser/type-parameters-in-field-exprs.stderr index e68e1f3204ade..2183c74da0acb 100644 --- a/src/test/ui/parser/type-parameters-in-field-exprs.stderr +++ b/src/test/ui/parser/type-parameters-in-field-exprs.stderr @@ -1,20 +1,20 @@ error: field expressions may not have generic arguments - --> $DIR/type-parameters-in-field-exprs.rs:13:8 + --> $DIR/type-parameters-in-field-exprs.rs:13:10 | LL | f.x::; - | ^^^^^^^^^ + | ^^^^^^^ error: field expressions may not have generic arguments - --> $DIR/type-parameters-in-field-exprs.rs:15:8 + --> $DIR/type-parameters-in-field-exprs.rs:15:10 | LL | f.x::<>; - | ^^^^ + | ^^ error: field expressions may not have generic arguments - --> $DIR/type-parameters-in-field-exprs.rs:17:8 + --> $DIR/type-parameters-in-field-exprs.rs:17:10 | LL | f.x::(); - | ^^^^ + | ^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/span/macro-ty-params.stderr b/src/test/ui/span/macro-ty-params.stderr index 23fdde06e8f9d..965ca7000be80 100644 --- a/src/test/ui/span/macro-ty-params.stderr +++ b/src/test/ui/span/macro-ty-params.stderr @@ -1,14 +1,14 @@ error: generic arguments in macro path - --> $DIR/macro-ty-params.rs:10:8 + --> $DIR/macro-ty-params.rs:10:10 | LL | foo::!(); //~ ERROR generic arguments in macro path - | ^^^^^ + | ^^^ error: generic arguments in macro path - --> $DIR/macro-ty-params.rs:11:8 + --> $DIR/macro-ty-params.rs:11:10 | LL | foo::<>!(); //~ ERROR generic arguments in macro path - | ^^^^ + | ^^ error: unexpected generic arguments in path --> $DIR/macro-ty-params.rs:12:8 diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs index 5387dcb218cb9..c96a6fa8b6c91 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs @@ -6,7 +6,8 @@ struct Bar { fn bar() { let x: Box = panic!(); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait + //~| ERROR wrong number of type arguments: expected 1, found 0 } fn main() { } diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr index 3f1b37c282b7c..fa52e66fb0349 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr @@ -1,9 +1,16 @@ -error[E0214]: parenthesized parameters may only be used with a trait +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:19 | LL | let x: Box = panic!(); - | ^^ only traits may use parentheses + | ^^ only `Fn` traits may use parentheses -error: aborting due to previous error +error[E0107]: wrong number of type arguments: expected 1, found 0 + --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:16 + | +LL | let x: Box = panic!(); + | ^^^^^ expected 1 type argument + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0214`. +Some errors occurred: E0107, E0214. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs index 3cada322b1ef2..79ced1ecfb1a0 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs @@ -12,7 +12,7 @@ fn bar() { let b = Bar::::new(); // OK let b = Bar::(isize, usize)::new(); // OK too (for the parser) - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait } fn main() {} diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr index 395f6596cfd83..7d05ca55ffdb0 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr @@ -1,8 +1,11 @@ -error[E0214]: parenthesized parameters may only be used with a trait - --> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:16 +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait + --> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:18 | LL | let b = Bar::(isize, usize)::new(); // OK too (for the parser) - | ^^^^^^^^^^^^^^^^ only traits may use parentheses + | ^^^^^^^^^^^^^^ + | | + | only `Fn` traits may use parentheses + | help: use angle brackets instead: `` error: aborting due to previous error diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs index e795650447cc4..1af7f55674c6a 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs @@ -5,8 +5,8 @@ struct Bar { } fn foo(b: Box) { - //~^ ERROR parenthesized parameters may only be used with a trait - //~| ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait + //~| ERROR wrong number of type arguments: expected 1, found 0 } fn main() { } diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr index d0267092030d8..b34237937ee1c 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr @@ -1,16 +1,16 @@ -error[E0214]: parenthesized parameters may only be used with a trait +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:18 | LL | fn foo(b: Box) { - | ^^ only traits may use parentheses + | ^^ only `Fn` traits may use parentheses -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0107]: wrong number of type arguments: expected 1, found 0 --> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:15 | LL | fn foo(b: Box) { - | ^^^^^ not allowed in type signatures + | ^^^^^ expected 1 type argument error: aborting due to 2 previous errors -Some errors occurred: E0121, E0214. -For more information about an error, try `rustc --explain E0121`. +Some errors occurred: E0107, E0214. +For more information about an error, try `rustc --explain E0107`.