Skip to content

Commit a5b9f2c

Browse files
committed
Auto merge of #53578 - varkor:disappearing-turbofish-crater-run, r=<try>
[Do not merge] Optional turbofish breakage test As an academic exercise, to satisfy ourselves that we completely understand the lay of the land, we'd like to see how often ambiguous cases arise in real-world Rust code. (Following on from #53511.) @rust-lang/infra: is it possible to get a check-only crater run for this change? r? @ghost
2 parents d0d81b7 + 01cb485 commit a5b9f2c

File tree

9 files changed

+77
-76
lines changed

9 files changed

+77
-76
lines changed

src/libsyntax/parse/parser.rs

+45-19
Original file line numberDiff line numberDiff line change
@@ -1714,11 +1714,10 @@ impl<'a> Parser<'a> {
17141714
} else if self.eat_keyword(keywords::Const) {
17151715
Mutability::Immutable
17161716
} else {
1717-
let span = self.prev_span;
1718-
self.span_err(span,
1719-
"expected mut or const in raw pointer type (use \
1720-
`*mut T` or `*const T` as appropriate)");
1721-
Mutability::Immutable
1717+
let mut err = self.fatal("expected mut or const in raw pointer type (use \
1718+
`*mut T` or `*const T` as appropriate)");
1719+
err.span_label(self.prev_span, "expected mut or const");
1720+
return Err(err);
17221721
};
17231722
let t = self.parse_ty_no_plus()?;
17241723
Ok(MutTy { ty: t, mutbl: mutbl })
@@ -2022,20 +2021,31 @@ impl<'a> Parser<'a> {
20222021
-> PResult<'a, PathSegment> {
20232022
let ident = self.parse_path_segment_ident()?;
20242023

2025-
let is_args_start = |token: &token::Token| match *token {
2026-
token::Lt | token::BinOp(token::Shl) | token::OpenDelim(token::Paren) => true,
2024+
let is_args_start = |token: &token::Token, include_paren: bool| match *token {
2025+
token::Lt | token::BinOp(token::Shl) => true,
2026+
token::OpenDelim(token::Paren) => include_paren,
20272027
_ => false,
20282028
};
2029-
let check_args_start = |this: &mut Self| {
2030-
this.expected_tokens.extend_from_slice(
2031-
&[TokenType::Token(token::Lt), TokenType::Token(token::OpenDelim(token::Paren))]
2032-
);
2033-
is_args_start(&this.token)
2029+
let check_args_start = |this: &mut Self, include_paren: bool| {
2030+
this.expected_tokens.push(TokenType::Token(token::Lt));
2031+
if include_paren {
2032+
this.expected_tokens.push(TokenType::Token(token::OpenDelim(token::Paren)));
2033+
}
2034+
is_args_start(&this.token, include_paren)
20342035
};
20352036

2036-
Ok(if style == PathStyle::Type && check_args_start(self) ||
2037-
style != PathStyle::Mod && self.check(&token::ModSep)
2038-
&& self.look_ahead(1, |t| is_args_start(t)) {
2037+
let mut parser_snapshot_before_generics = None;
2038+
2039+
Ok(if style == PathStyle::Type && check_args_start(self, true)
2040+
|| style != PathStyle::Mod && self.check(&token::ModSep)
2041+
&& self.look_ahead(1, |t| is_args_start(t, true))
2042+
|| style == PathStyle::Expr && check_args_start(self, false) && {
2043+
// Check for generic arguments in an expression without a disambiguating `::`.
2044+
// We have to save a snapshot, because it could end up being an expression
2045+
// instead.
2046+
parser_snapshot_before_generics = Some(self.clone());
2047+
true
2048+
} {
20392049
// Generic arguments are found - `<`, `(`, `::<` or `::(`.
20402050
let lo = self.span;
20412051
if self.eat(&token::ModSep) && style == PathStyle::Type && enable_warning {
@@ -2045,10 +2055,26 @@ impl<'a> Parser<'a> {
20452055

20462056
let args = if self.eat_lt() {
20472057
// `<'a, T, A = U>`
2048-
let (args, bindings) = self.parse_generic_args()?;
2049-
self.expect_gt()?;
2050-
let span = lo.to(self.prev_span);
2051-
AngleBracketedArgs { args, bindings, span }.into()
2058+
let args: PResult<_> = do catch {
2059+
let (args, bindings) = self.parse_generic_args()?;
2060+
self.expect_gt()?;
2061+
let span = lo.to(self.prev_span);
2062+
AngleBracketedArgs { args, bindings, span }
2063+
};
2064+
2065+
match args {
2066+
Err(mut err) => {
2067+
if let Some(snapshot) = parser_snapshot_before_generics {
2068+
err.cancel();
2069+
mem::replace(self, snapshot);
2070+
return Ok(PathSegment::from_ident(ident));
2071+
}
2072+
return Err(err);
2073+
}
2074+
_ => {
2075+
args?.into()
2076+
}
2077+
}
20522078
} else {
20532079
// `(T, U) -> R`
20542080
self.bump(); // `(`

src/libsyntax/parse/token.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ pub enum Token {
167167
Comma,
168168
Semi,
169169
Colon,
170-
ModSep,
170+
ModSep, // `::`
171171
RArrow,
172172
LArrow,
173173
FatArrow,

src/test/parse-fail/pat-ranges-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111
// Parsing of range patterns
1212

1313
fn main() {
14-
let 10 ..= makropulos!() = 12; //~ error: expected one of `::`, `:`, `;`, or `=`, found `!`
14+
let 10 ..= makropulos!() = 12; //~ error: expected one of `::`, `:`, `;`, `<`, or `=`, found `!`
1515
}

src/test/parse-fail/require-parens-for-chained-comparison.rs

-5
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,4 @@ fn main() {
1818

1919
false == 0 < 2;
2020
//~^ ERROR: chained comparison operators require parentheses
21-
22-
f<X>();
23-
//~^ ERROR: chained comparison operators require parentheses
24-
//~| HELP: use `::<...>` instead of `<...>`
25-
//~| HELP: or use `(...)`
2621
}

src/test/ui/did_you_mean/issue-40396.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
99
// except according to those terms.
1010

1111
fn foo() {
12-
println!("{:?}", (0..13).collect<Vec<i32>>()); //~ ERROR chained comparison
12+
println!("{:?}", (0..13).collect<Vec<i32>>()); // ok
1313
}
1414

1515
fn bar() {
16-
println!("{:?}", Vec<i32>::new()); //~ ERROR chained comparison
16+
println!("{:?}", Vec<i32>::new()); // ok
1717
}
1818

1919
fn qux() {
20-
println!("{:?}", (0..13).collect<Vec<i32>()); //~ ERROR chained comparison
21-
//~^ ERROR chained comparison
20+
println!("{:?}", (0..13).collect<Vec<i32>()); //~ ERROR expected function, found struct `Vec`
21+
//~^ ERROR attempted to take value of method `collect`
2222
}
2323

2424
fn main() {}
+12-32
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,18 @@
1-
error: chained comparison operators require parentheses
2-
--> $DIR/issue-40396.rs:12:37
1+
error[E0423]: expected function, found struct `Vec`
2+
--> $DIR/issue-40396.rs:20:38
33
|
4-
LL | println!("{:?}", (0..13).collect<Vec<i32>>()); //~ ERROR chained comparison
5-
| ^^^^^^^^
6-
|
7-
= help: use `::<...>` instead of `<...>` if you meant to specify type arguments
8-
= help: or use `(...)` if you meant to specify fn arguments
9-
10-
error: chained comparison operators require parentheses
11-
--> $DIR/issue-40396.rs:16:25
12-
|
13-
LL | println!("{:?}", Vec<i32>::new()); //~ ERROR chained comparison
14-
| ^^^^^^^
15-
|
16-
= help: use `::<...>` instead of `<...>` if you meant to specify type arguments
17-
= help: or use `(...)` if you meant to specify fn arguments
18-
19-
error: chained comparison operators require parentheses
20-
--> $DIR/issue-40396.rs:20:37
21-
|
22-
LL | println!("{:?}", (0..13).collect<Vec<i32>()); //~ ERROR chained comparison
23-
| ^^^^^^^^
24-
|
25-
= help: use `::<...>` instead of `<...>` if you meant to specify type arguments
26-
= help: or use `(...)` if you meant to specify fn arguments
4+
LL | println!("{:?}", (0..13).collect<Vec<i32>()); //~ ERROR expected function, found struct `Vec`
5+
| ^^^^^^^^ did you mean `Vec { /* fields */ }`?
276

28-
error: chained comparison operators require parentheses
29-
--> $DIR/issue-40396.rs:20:41
7+
error[E0615]: attempted to take value of method `collect` on type `std::ops::Range<{integer}>`
8+
--> $DIR/issue-40396.rs:20:30
309
|
31-
LL | println!("{:?}", (0..13).collect<Vec<i32>()); //~ ERROR chained comparison
32-
| ^^^^^^
10+
LL | println!("{:?}", (0..13).collect<Vec<i32>()); //~ ERROR expected function, found struct `Vec`
11+
| ^^^^^^^
3312
|
34-
= help: use `::<...>` instead of `<...>` if you meant to specify type arguments
35-
= help: or use `(...)` if you meant to specify fn arguments
13+
= help: maybe a `()` to call it is missing?
3614

37-
error: aborting due to 4 previous errors
15+
error: aborting due to 2 previous errors
3816

17+
Some errors occurred: E0423, E0615.
18+
For more information about an error, try `rustc --explain E0423`.

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ LL | { $inp $nonexistent }
77
LL | g!(foo);
88
| -------- in this macro invocation
99

10-
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `nonexistent`
10+
error: expected one of `!`, `.`, `::`, `;`, `<`, `?`, `{`, `}`, or an operator, found `nonexistent`
1111
--> $DIR/issue-6596-2.rs:15:16
1212
|
1313
LL | { $inp $nonexistent }
14-
| ^^^^^^^^^^^^ expected one of 8 possible tokens here
14+
| ^^^^^^^^^^^^ expected one of 9 possible tokens here
1515
...
1616
LL | g!(foo);
1717
| -------- in this macro invocation

src/test/ui/macro_backtrace/main.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
1+
error: expected one of `!`, `.`, `::`, `;`, `<`, `?`, `{`, `}`, or an operator, found `error`
22
--> $DIR/main.rs:19:20
33
|
44
LL | / macro_rules! pong {
55
LL | | () => { syntax error };
6-
| | ^^^^^ expected one of 8 possible tokens here
6+
| | ^^^^^ expected one of 9 possible tokens here
77
LL | | }
88
| |_- in this expansion of `pong!`
99
...
1010
LL | pong!();
1111
| -------- in this macro invocation
1212

13-
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
13+
error: expected one of `!`, `.`, `::`, `;`, `<`, `?`, `{`, `}`, or an operator, found `error`
1414
--> $DIR/main.rs:19:20
1515
|
1616
LL | / macro_rules! pong {
1717
LL | | () => { syntax error };
18-
| | ^^^^^ expected one of 8 possible tokens here
18+
| | ^^^^^ expected one of 9 possible tokens here
1919
LL | | }
2020
| |_- in this expansion of `pong!`
2121
...
@@ -30,12 +30,12 @@ LL | ( ) => { pong ! ( ) ; }
3030
| | in this macro invocation
3131
| in this expansion of `ping!`
3232

33-
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
33+
error: expected one of `!`, `.`, `::`, `;`, `<`, `?`, `{`, `}`, or an operator, found `error`
3434
--> $DIR/main.rs:19:20
3535
|
3636
LL | / macro_rules! pong {
3737
LL | | () => { syntax error };
38-
| | ^^^^^ expected one of 8 possible tokens here
38+
| | ^^^^^ expected one of 9 possible tokens here
3939
LL | | }
4040
| |_- in this expansion of `pong!` (#5)
4141
...
+6-6
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `true`
1+
error: expected one of `!`, `.`, `::`, `;`, `<`, `?`, `{`, `}`, or an operator, found `true`
22
--> $DIR/raw-literal-keywords.rs:14:10
33
|
44
LL | r#if true { } //~ ERROR found `true`
5-
| ^^^^ expected one of 8 possible tokens here
5+
| ^^^^ expected one of 9 possible tokens here
66

7-
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test`
7+
error: expected one of `!`, `.`, `::`, `;`, `<`, `?`, `{`, `}`, or an operator, found `Test`
88
--> $DIR/raw-literal-keywords.rs:18:14
99
|
1010
LL | r#struct Test; //~ ERROR found `Test`
11-
| ^^^^ expected one of 8 possible tokens here
11+
| ^^^^ expected one of 9 possible tokens here
1212

13-
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test`
13+
error: expected one of `!`, `.`, `::`, `;`, `<`, `?`, `{`, `}`, or an operator, found `Test`
1414
--> $DIR/raw-literal-keywords.rs:22:13
1515
|
1616
LL | r#union Test; //~ ERROR found `Test`
17-
| ^^^^ expected one of 8 possible tokens here
17+
| ^^^^ expected one of 9 possible tokens here
1818

1919
error: aborting due to 3 previous errors
2020

0 commit comments

Comments
 (0)