Skip to content

Continue parsing after parent type args and suggest using angle brackets #57768

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -1806,7 +1807,7 @@ impl<'a> LoweringContext<'a> {
explicit_owner: Option<NodeId>,
) -> 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)
Expand All @@ -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)
}
},
}
Expand Down
10 changes: 10 additions & 0 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,16 @@ pub struct ParenthesisedArgs {
pub output: Option<P<Ty>>,
}

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;
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>`
Expand Down
7 changes: 5 additions & 2 deletions src/test/ui/error-codes/E0214.stderr
Original file line number Diff line number Diff line change
@@ -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

Expand Down
3 changes: 2 additions & 1 deletion src/test/ui/issues/issue-23589.rs
Original file line number Diff line number Diff line change
@@ -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
}
21 changes: 17 additions & 4 deletions src/test/ui/issues/issue-23589.stderr
Original file line number Diff line number Diff line change
@@ -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`.
6 changes: 3 additions & 3 deletions src/test/ui/issues/issue-32995-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

fn main() {
{ fn f<X: ::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

{ 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
}

#[derive(Clone)]
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
6 changes: 3 additions & 3 deletions src/test/ui/issues/issue-32995-2.stderr
Original file line number Diff line number Diff line change
@@ -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<X: ::std::marker()::Send>() {} }
Expand All @@ -8,7 +8,7 @@ LL | { fn f<X: ::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 <https://github.com/rust-lang/rust/issues/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 { } }
Expand All @@ -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 <https://github.com/rust-lang/rust/issues/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 {}
Expand Down
14 changes: 7 additions & 7 deletions src/test/ui/issues/issue-32995.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Send + ::std::marker()::Sync> = 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<X:Default>() {
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
}
22 changes: 11 additions & 11 deletions src/test/ui/issues/issue-32995.stderr
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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 <https://github.com/rust-lang/rust/issues/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);
Expand All @@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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);
Expand All @@ -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 <https://github.com/rust-lang/rust/issues/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<Send + ::std::marker()::Sync> = Box::new(1);
Expand All @@ -53,7 +53,7 @@ LL | let o : Box<Send + ::std::marker()::Sync> = 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 <https://github.com/rust-lang/rust/issues/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();
Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/parser/type-parameters-in-field-exprs.stderr
Original file line number Diff line number Diff line change
@@ -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::<isize>;
| ^^^^^^^^^
| ^^^^^^^

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

8 changes: 4 additions & 4 deletions src/test/ui/span/macro-ty-params.stderr
Original file line number Diff line number Diff line change
@@ -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::<T>!(); //~ 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ struct Bar<A> {

fn bar() {
let x: Box<Bar()> = 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() { }
Original file line number Diff line number Diff line change
@@ -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<Bar()> = 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<Bar()> = 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`.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn bar() {
let b = Bar::<isize, usize>::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() {}
Original file line number Diff line number Diff line change
@@ -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: `<isize, usize>`

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ struct Bar<A> {
}

fn foo(b: Box<Bar()>) {
//~^ 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() { }
Loading