Skip to content

Commit d333752

Browse files
committed
Fix parsing of paths with fn-like generic arguments
1 parent eef85cf commit d333752

File tree

3 files changed

+18
-24
lines changed

3 files changed

+18
-24
lines changed

src/libsyntax/parse/parser.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -1467,7 +1467,7 @@ impl<'a> Parser<'a> {
14671467

14681468
// Parse a type
14691469
pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
1470-
self.parse_ty_common(true)
1470+
self.parse_ty_common(true, true)
14711471
}
14721472

14731473
/// Parse a type in restricted contexts where `+` is not permitted.
@@ -1476,10 +1476,11 @@ impl<'a> Parser<'a> {
14761476
/// Example 2: `value1 as TYPE + value2`
14771477
/// `+` is prohibited to avoid interactions with expression grammar.
14781478
fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
1479-
self.parse_ty_common(false)
1479+
self.parse_ty_common(false, true)
14801480
}
14811481

1482-
fn parse_ty_common(&mut self, allow_plus: bool) -> PResult<'a, P<Ty>> {
1482+
fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool)
1483+
-> PResult<'a, P<Ty>> {
14831484
maybe_whole!(self, NtTy, |x| x);
14841485

14851486
let lo = self.span;
@@ -1612,7 +1613,7 @@ impl<'a> Parser<'a> {
16121613

16131614
// Try to recover from use of `+` with incorrect priority.
16141615
self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?;
1615-
let ty = self.maybe_recover_from_bad_qpath(ty)?;
1616+
let ty = self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery)?;
16161617

16171618
Ok(P(ty))
16181619
}
@@ -1668,9 +1669,10 @@ impl<'a> Parser<'a> {
16681669
}
16691670

16701671
// Try to recover from associated item paths like `[T]::AssocItem`/`(T, U)::AssocItem`.
1671-
fn maybe_recover_from_bad_qpath<T: RecoverQPath>(&mut self, base: T) -> PResult<'a, T> {
1672+
fn maybe_recover_from_bad_qpath<T: RecoverQPath>(&mut self, base: T, allow_recovery: bool)
1673+
-> PResult<'a, T> {
16721674
// Do not add `::` to expected tokens.
1673-
if self.token != token::ModSep {
1675+
if !allow_recovery || self.token != token::ModSep {
16741676
return Ok(base);
16751677
}
16761678
let ty = match base.to_ty() {
@@ -2004,7 +2006,7 @@ impl<'a> Parser<'a> {
20042006
|p| p.parse_ty())?;
20052007
self.bump(); // `)`
20062008
let output = if self.eat(&token::RArrow) {
2007-
Some(self.parse_ty_no_plus()?)
2009+
Some(self.parse_ty_common(false, false)?)
20082010
} else {
20092011
None
20102012
};
@@ -2411,7 +2413,7 @@ impl<'a> Parser<'a> {
24112413
}
24122414

24132415
let expr = Expr { node: ex, span: lo.to(hi), id: ast::DUMMY_NODE_ID, attrs };
2414-
let expr = self.maybe_recover_from_bad_qpath(expr)?;
2416+
let expr = self.maybe_recover_from_bad_qpath(expr, true)?;
24152417

24162418
return Ok(P(expr));
24172419
}
@@ -3778,7 +3780,7 @@ impl<'a> Parser<'a> {
37783780
}
37793781

37803782
let pat = Pat { node: pat, span: lo.to(self.prev_span), id: ast::DUMMY_NODE_ID };
3781-
let pat = self.maybe_recover_from_bad_qpath(pat)?;
3783+
let pat = self.maybe_recover_from_bad_qpath(pat, true)?;
37823784

37833785
Ok(P(pat))
37843786
}

src/test/ui/did_you_mean/bad-assoc-ty.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,9 @@ type G = 'static + (Send)::AssocTy;
3838
//~^ ERROR missing angle brackets in associated item path
3939
//~| ERROR ambiguous associated type
4040

41-
// FIXME
4241
// This is actually a legal path with fn-like generic arguments in the middle!
4342
// Recovery should not apply in this context.
4443
type H = Fn(u8) -> (u8)::Output;
45-
//~^ ERROR missing angle brackets in associated item path
46-
//~| ERROR ambiguous associated type
44+
//~^ ERROR ambiguous associated type
4745

4846
fn main() {}

src/test/ui/did_you_mean/bad-assoc-ty.stderr

+6-12
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,7 @@ error: missing angle brackets in associated item path
3838
--> $DIR/bad-assoc-ty.rs:37:10
3939
|
4040
37 | type G = 'static + (Send)::AssocTy;
41-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `< 'static + Send>::AssocTy`
42-
43-
error: missing angle brackets in associated item path
44-
--> $DIR/bad-assoc-ty.rs:44:20
45-
|
46-
44 | type H = Fn(u8) -> (u8)::Output;
47-
| ^^^^^^^^^^^^ help: try: `<(u8)>::Output`
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<'static + Send>::AssocTy`
4842

4943
error[E0223]: ambiguous associated type
5044
--> $DIR/bad-assoc-ty.rs:11:10
@@ -101,12 +95,12 @@ error[E0223]: ambiguous associated type
10195
= note: specify the type using the syntax `<std::marker::Send + 'static as Trait>::AssocTy`
10296

10397
error[E0223]: ambiguous associated type
104-
--> $DIR/bad-assoc-ty.rs:44:20
98+
--> $DIR/bad-assoc-ty.rs:43:10
10599
|
106-
44 | type H = Fn(u8) -> (u8)::Output;
107-
| ^^^^^^^^^^^^ ambiguous associated type
100+
43 | type H = Fn(u8) -> (u8)::Output;
101+
| ^^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
108102
|
109-
= note: specify the type using the syntax `<u8 as Trait>::Output`
103+
= note: specify the type using the syntax `<std::ops::Fn(u8) -> u8 + 'static as Trait>::Output`
110104

111-
error: aborting due to 16 previous errors
105+
error: aborting due to 15 previous errors
112106

0 commit comments

Comments
 (0)