Skip to content

Commit 627e001

Browse files
authored
Rollup merge of #57768 - estebank:type-args-sugg, r=zackmdavis
Continue parsing after parent type args and suggest using angle brackets ``` error[E0214]: parenthesized parameters may only be used with a trait --> $DIR/E0214.rs:2:15 | LL | let v: Vec(&str) = vec!["foo"]; | ^^^^^^ | | | only traits may use parentheses | help: use angle brackets instead: `<&str>` ``` r? @zackmdavis
2 parents ebc70e2 + 2ab6cef commit 627e001

18 files changed

+118
-64
lines changed

src/librustc/hir/lowering.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
//! in the HIR, especially for multiple identifiers.
3232
3333
use dep_graph::DepGraph;
34+
use errors::Applicability;
3435
use hir::{self, ParamName};
3536
use hir::HirVec;
3637
use hir::map::{DefKey, DefPathData, Definitions};
@@ -1806,7 +1807,7 @@ impl<'a> LoweringContext<'a> {
18061807
explicit_owner: Option<NodeId>,
18071808
) -> hir::PathSegment {
18081809
let (mut generic_args, infer_types) = if let Some(ref generic_args) = segment.args {
1809-
let msg = "parenthesized parameters may only be used with a trait";
1810+
let msg = "parenthesized type parameters may only be used with a `Fn` trait";
18101811
match **generic_args {
18111812
GenericArgs::AngleBracketed(ref data) => {
18121813
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
@@ -1823,10 +1824,25 @@ impl<'a> LoweringContext<'a> {
18231824
(hir::GenericArgs::none(), true)
18241825
}
18251826
ParenthesizedGenericArgs::Err => {
1826-
struct_span_err!(self.sess, data.span, E0214, "{}", msg)
1827-
.span_label(data.span, "only traits may use parentheses")
1828-
.emit();
1829-
(hir::GenericArgs::none(), true)
1827+
let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg);
1828+
err.span_label(data.span, "only `Fn` traits may use parentheses");
1829+
if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
1830+
// Do not suggest going from `Trait()` to `Trait<>`
1831+
if data.inputs.len() > 0 {
1832+
err.span_suggestion_with_applicability(
1833+
data.span,
1834+
"use angle brackets instead",
1835+
format!("<{}>", &snippet[1..snippet.len() - 1]),
1836+
Applicability::MaybeIncorrect,
1837+
);
1838+
}
1839+
};
1840+
err.emit();
1841+
(self.lower_angle_bracketed_parameter_data(
1842+
&data.as_angle_bracketed_args(),
1843+
param_mode,
1844+
itctx).0,
1845+
false)
18301846
}
18311847
},
18321848
}

src/libsyntax/ast.rs

+10
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,16 @@ pub struct ParenthesisedArgs {
192192
pub output: Option<P<Ty>>,
193193
}
194194

195+
impl ParenthesisedArgs {
196+
pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
197+
AngleBracketedArgs {
198+
span: self.span,
199+
args: self.inputs.iter().cloned().map(|input| GenericArg::Type(input)).collect(),
200+
bindings: vec![],
201+
}
202+
}
203+
}
204+
195205
// hack to ensure that we don't try to access the private parts of `NodeId` in this module
196206
mod node_id_inner {
197207
use rustc_data_structures::indexed_vec::Idx;

src/libsyntax/parse/parser.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2176,11 +2176,11 @@ impl<'a> Parser<'a> {
21762176
style != PathStyle::Mod && self.check(&token::ModSep)
21772177
&& self.look_ahead(1, |t| is_args_start(t)) {
21782178
// Generic arguments are found - `<`, `(`, `::<` or `::(`.
2179-
let lo = self.span;
21802179
if self.eat(&token::ModSep) && style == PathStyle::Type && enable_warning {
21812180
self.diagnostic().struct_span_warn(self.prev_span, "unnecessary path disambiguator")
21822181
.span_label(self.prev_span, "try removing `::`").emit();
21832182
}
2183+
let lo = self.span;
21842184

21852185
let args = if self.eat_lt() {
21862186
// `<'a, T, A = U>`

src/test/ui/error-codes/E0214.stderr

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
error[E0214]: parenthesized parameters may only be used with a trait
1+
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
22
--> $DIR/E0214.rs:2:15
33
|
44
LL | let v: Vec(&str) = vec!["foo"];
5-
| ^^^^^^ only traits may use parentheses
5+
| ^^^^^^
6+
| |
7+
| only `Fn` traits may use parentheses
8+
| help: use angle brackets instead: `<&str>`
69

710
error: aborting due to previous error
811

src/test/ui/issues/issue-23589.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
fn main() {
22
let v: Vec(&str) = vec!['1', '2'];
3-
//~^ ERROR parenthesized parameters may only be used with a trait
3+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
4+
//~| ERROR mismatched types
45
}

src/test/ui/issues/issue-23589.stderr

+17-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
1-
error[E0214]: parenthesized parameters may only be used with a trait
1+
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
22
--> $DIR/issue-23589.rs:2:15
33
|
44
LL | let v: Vec(&str) = vec!['1', '2'];
5-
| ^^^^^^ only traits may use parentheses
5+
| ^^^^^^
6+
| |
7+
| only `Fn` traits may use parentheses
8+
| help: use angle brackets instead: `<&str>`
69

7-
error: aborting due to previous error
10+
error[E0308]: mismatched types
11+
--> $DIR/issue-23589.rs:2:29
12+
|
13+
LL | let v: Vec(&str) = vec!['1', '2'];
14+
| ^^^ expected &str, found char
15+
|
16+
= note: expected type `&str`
17+
found type `char`
18+
19+
error: aborting due to 2 previous errors
820

9-
For more information about this error, try `rustc --explain E0214`.
21+
Some errors occurred: E0214, E0308.
22+
For more information about an error, try `rustc --explain E0214`.

src/test/ui/issues/issue-32995-2.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22

33
fn main() {
44
{ fn f<X: ::std::marker()::Send>() {} }
5-
//~^ ERROR parenthesized parameters may only be used with a trait
5+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
66
//~| WARN previously accepted
77

88
{ fn f() -> impl ::std::marker()::Send { } }
9-
//~^ ERROR parenthesized parameters may only be used with a trait
9+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
1010
//~| WARN previously accepted
1111
}
1212

1313
#[derive(Clone)]
1414
struct X;
1515

1616
impl ::std::marker()::Copy for X {}
17-
//~^ ERROR parenthesized parameters may only be used with a trait
17+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
1818
//~| WARN previously accepted

src/test/ui/issues/issue-32995-2.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: parenthesized parameters may only be used with a trait
1+
error: parenthesized type parameters may only be used with a `Fn` trait
22
--> $DIR/issue-32995-2.rs:4:28
33
|
44
LL | { fn f<X: ::std::marker()::Send>() {} }
@@ -8,7 +8,7 @@ LL | { fn f<X: ::std::marker()::Send>() {} }
88
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
1010

11-
error: parenthesized parameters may only be used with a trait
11+
error: parenthesized type parameters may only be used with a `Fn` trait
1212
--> $DIR/issue-32995-2.rs:8:35
1313
|
1414
LL | { fn f() -> impl ::std::marker()::Send { } }
@@ -17,7 +17,7 @@ LL | { fn f() -> impl ::std::marker()::Send { } }
1717
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
1818
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
1919

20-
error: parenthesized parameters may only be used with a trait
20+
error: parenthesized type parameters may only be used with a `Fn` trait
2121
--> $DIR/issue-32995-2.rs:16:19
2222
|
2323
LL | impl ::std::marker()::Copy for X {}

src/test/ui/issues/issue-32995.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,32 @@
22

33
fn main() {
44
let x: usize() = 1;
5-
//~^ ERROR parenthesized parameters may only be used with a trait
5+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
66
//~| WARN previously accepted
77

88
let b: ::std::boxed()::Box<_> = Box::new(1);
9-
//~^ ERROR parenthesized parameters may only be used with a trait
9+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
1010
//~| WARN previously accepted
1111

1212
let p = ::std::str::()::from_utf8(b"foo").unwrap();
13-
//~^ ERROR parenthesized parameters may only be used with a trait
13+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
1414
//~| WARN previously accepted
1515

1616
let p = ::std::str::from_utf8::()(b"foo").unwrap();
17-
//~^ ERROR parenthesized parameters may only be used with a trait
17+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
1818
//~| WARN previously accepted
1919

2020
let o : Box<::std::marker()::Send> = Box::new(1);
21-
//~^ ERROR parenthesized parameters may only be used with a trait
21+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
2222
//~| WARN previously accepted
2323

2424
let o : Box<Send + ::std::marker()::Sync> = Box::new(1);
25-
//~^ ERROR parenthesized parameters may only be used with a trait
25+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
2626
//~| WARN previously accepted
2727
}
2828

2929
fn foo<X:Default>() {
3030
let d : X() = Default::default();
31-
//~^ ERROR parenthesized parameters may only be used with a trait
31+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
3232
//~| WARN previously accepted
3333
}

src/test/ui/issues/issue-32995.stderr

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: parenthesized parameters may only be used with a trait
1+
error: parenthesized type parameters may only be used with a `Fn` trait
22
--> $DIR/issue-32995.rs:4:17
33
|
44
LL | let x: usize() = 1;
@@ -8,7 +8,7 @@ LL | let x: usize() = 1;
88
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
1010

11-
error: parenthesized parameters may only be used with a trait
11+
error: parenthesized type parameters may only be used with a `Fn` trait
1212
--> $DIR/issue-32995.rs:8:24
1313
|
1414
LL | let b: ::std::boxed()::Box<_> = Box::new(1);
@@ -17,25 +17,25 @@ LL | let b: ::std::boxed()::Box<_> = Box::new(1);
1717
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
1818
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
1919

20-
error: parenthesized parameters may only be used with a trait
21-
--> $DIR/issue-32995.rs:12:23
20+
error: parenthesized type parameters may only be used with a `Fn` trait
21+
--> $DIR/issue-32995.rs:12:25
2222
|
2323
LL | let p = ::std::str::()::from_utf8(b"foo").unwrap();
24-
| ^^^^
24+
| ^^
2525
|
2626
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2727
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
2828

29-
error: parenthesized parameters may only be used with a trait
30-
--> $DIR/issue-32995.rs:16:34
29+
error: parenthesized type parameters may only be used with a `Fn` trait
30+
--> $DIR/issue-32995.rs:16:36
3131
|
3232
LL | let p = ::std::str::from_utf8::()(b"foo").unwrap();
33-
| ^^^^
33+
| ^^
3434
|
3535
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3636
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
3737

38-
error: parenthesized parameters may only be used with a trait
38+
error: parenthesized type parameters may only be used with a `Fn` trait
3939
--> $DIR/issue-32995.rs:20:30
4040
|
4141
LL | let o : Box<::std::marker()::Send> = Box::new(1);
@@ -44,7 +44,7 @@ LL | let o : Box<::std::marker()::Send> = Box::new(1);
4444
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4545
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
4646

47-
error: parenthesized parameters may only be used with a trait
47+
error: parenthesized type parameters may only be used with a `Fn` trait
4848
--> $DIR/issue-32995.rs:24:37
4949
|
5050
LL | let o : Box<Send + ::std::marker()::Sync> = Box::new(1);
@@ -53,7 +53,7 @@ LL | let o : Box<Send + ::std::marker()::Sync> = Box::new(1);
5353
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5454
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
5555

56-
error: parenthesized parameters may only be used with a trait
56+
error: parenthesized type parameters may only be used with a `Fn` trait
5757
--> $DIR/issue-32995.rs:30:14
5858
|
5959
LL | let d : X() = Default::default();
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
error: field expressions may not have generic arguments
2-
--> $DIR/type-parameters-in-field-exprs.rs:13:8
2+
--> $DIR/type-parameters-in-field-exprs.rs:13:10
33
|
44
LL | f.x::<isize>;
5-
| ^^^^^^^^^
5+
| ^^^^^^^
66

77
error: field expressions may not have generic arguments
8-
--> $DIR/type-parameters-in-field-exprs.rs:15:8
8+
--> $DIR/type-parameters-in-field-exprs.rs:15:10
99
|
1010
LL | f.x::<>;
11-
| ^^^^
11+
| ^^
1212

1313
error: field expressions may not have generic arguments
14-
--> $DIR/type-parameters-in-field-exprs.rs:17:8
14+
--> $DIR/type-parameters-in-field-exprs.rs:17:10
1515
|
1616
LL | f.x::();
17-
| ^^^^
17+
| ^^
1818

1919
error: aborting due to 3 previous errors
2020

src/test/ui/span/macro-ty-params.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
error: generic arguments in macro path
2-
--> $DIR/macro-ty-params.rs:10:8
2+
--> $DIR/macro-ty-params.rs:10:10
33
|
44
LL | foo::<T>!(); //~ ERROR generic arguments in macro path
5-
| ^^^^^
5+
| ^^^
66

77
error: generic arguments in macro path
8-
--> $DIR/macro-ty-params.rs:11:8
8+
--> $DIR/macro-ty-params.rs:11:10
99
|
1010
LL | foo::<>!(); //~ ERROR generic arguments in macro path
11-
| ^^^^
11+
| ^^
1212

1313
error: unexpected generic arguments in path
1414
--> $DIR/macro-ty-params.rs:12:8

src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ struct Bar<A> {
66

77
fn bar() {
88
let x: Box<Bar()> = panic!();
9-
//~^ ERROR parenthesized parameters may only be used with a trait
9+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
10+
//~| ERROR wrong number of type arguments: expected 1, found 0
1011
}
1112

1213
fn main() { }
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
error[E0214]: parenthesized parameters may only be used with a trait
1+
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
22
--> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:19
33
|
44
LL | let x: Box<Bar()> = panic!();
5-
| ^^ only traits may use parentheses
5+
| ^^ only `Fn` traits may use parentheses
66

7-
error: aborting due to previous error
7+
error[E0107]: wrong number of type arguments: expected 1, found 0
8+
--> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:16
9+
|
10+
LL | let x: Box<Bar()> = panic!();
11+
| ^^^^^ expected 1 type argument
12+
13+
error: aborting due to 2 previous errors
814

9-
For more information about this error, try `rustc --explain E0214`.
15+
Some errors occurred: E0107, E0214.
16+
For more information about an error, try `rustc --explain E0107`.

src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn bar() {
1212
let b = Bar::<isize, usize>::new(); // OK
1313

1414
let b = Bar::(isize, usize)::new(); // OK too (for the parser)
15-
//~^ ERROR parenthesized parameters may only be used with a trait
15+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
1616
}
1717

1818
fn main() {}

src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
error[E0214]: parenthesized parameters may only be used with a trait
2-
--> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:16
1+
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
2+
--> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:18
33
|
44
LL | let b = Bar::(isize, usize)::new(); // OK too (for the parser)
5-
| ^^^^^^^^^^^^^^^^ only traits may use parentheses
5+
| ^^^^^^^^^^^^^^
6+
| |
7+
| only `Fn` traits may use parentheses
8+
| help: use angle brackets instead: `<isize, usize>`
69

710
error: aborting due to previous error
811

src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ struct Bar<A> {
55
}
66

77
fn foo(b: Box<Bar()>) {
8-
//~^ ERROR parenthesized parameters may only be used with a trait
9-
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
8+
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
9+
//~| ERROR wrong number of type arguments: expected 1, found 0
1010
}
1111

1212
fn main() { }

0 commit comments

Comments
 (0)