Fix parsing of paths with fn-like generic arguments
This commit is contained in:
parent
eef85cf0ff
commit
d333752f5c
3 changed files with 18 additions and 24 deletions
|
@ -1467,7 +1467,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
// Parse a type
|
// Parse a type
|
||||||
pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
|
pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
|
||||||
self.parse_ty_common(true)
|
self.parse_ty_common(true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a type in restricted contexts where `+` is not permitted.
|
/// Parse a type in restricted contexts where `+` is not permitted.
|
||||||
|
@ -1476,10 +1476,11 @@ impl<'a> Parser<'a> {
|
||||||
/// Example 2: `value1 as TYPE + value2`
|
/// Example 2: `value1 as TYPE + value2`
|
||||||
/// `+` is prohibited to avoid interactions with expression grammar.
|
/// `+` is prohibited to avoid interactions with expression grammar.
|
||||||
fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
|
fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
|
||||||
self.parse_ty_common(false)
|
self.parse_ty_common(false, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_ty_common(&mut self, allow_plus: bool) -> PResult<'a, P<Ty>> {
|
fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool)
|
||||||
|
-> PResult<'a, P<Ty>> {
|
||||||
maybe_whole!(self, NtTy, |x| x);
|
maybe_whole!(self, NtTy, |x| x);
|
||||||
|
|
||||||
let lo = self.span;
|
let lo = self.span;
|
||||||
|
@ -1612,7 +1613,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
// Try to recover from use of `+` with incorrect priority.
|
// Try to recover from use of `+` with incorrect priority.
|
||||||
self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?;
|
self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?;
|
||||||
let ty = self.maybe_recover_from_bad_qpath(ty)?;
|
let ty = self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery)?;
|
||||||
|
|
||||||
Ok(P(ty))
|
Ok(P(ty))
|
||||||
}
|
}
|
||||||
|
@ -1668,9 +1669,10 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to recover from associated item paths like `[T]::AssocItem`/`(T, U)::AssocItem`.
|
// Try to recover from associated item paths like `[T]::AssocItem`/`(T, U)::AssocItem`.
|
||||||
fn maybe_recover_from_bad_qpath<T: RecoverQPath>(&mut self, base: T) -> PResult<'a, T> {
|
fn maybe_recover_from_bad_qpath<T: RecoverQPath>(&mut self, base: T, allow_recovery: bool)
|
||||||
|
-> PResult<'a, T> {
|
||||||
// Do not add `::` to expected tokens.
|
// Do not add `::` to expected tokens.
|
||||||
if self.token != token::ModSep {
|
if !allow_recovery || self.token != token::ModSep {
|
||||||
return Ok(base);
|
return Ok(base);
|
||||||
}
|
}
|
||||||
let ty = match base.to_ty() {
|
let ty = match base.to_ty() {
|
||||||
|
@ -2004,7 +2006,7 @@ impl<'a> Parser<'a> {
|
||||||
|p| p.parse_ty())?;
|
|p| p.parse_ty())?;
|
||||||
self.bump(); // `)`
|
self.bump(); // `)`
|
||||||
let output = if self.eat(&token::RArrow) {
|
let output = if self.eat(&token::RArrow) {
|
||||||
Some(self.parse_ty_no_plus()?)
|
Some(self.parse_ty_common(false, false)?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -2411,7 +2413,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let expr = Expr { node: ex, span: lo.to(hi), id: ast::DUMMY_NODE_ID, attrs };
|
let expr = Expr { node: ex, span: lo.to(hi), id: ast::DUMMY_NODE_ID, attrs };
|
||||||
let expr = self.maybe_recover_from_bad_qpath(expr)?;
|
let expr = self.maybe_recover_from_bad_qpath(expr, true)?;
|
||||||
|
|
||||||
return Ok(P(expr));
|
return Ok(P(expr));
|
||||||
}
|
}
|
||||||
|
@ -3778,7 +3780,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let pat = Pat { node: pat, span: lo.to(self.prev_span), id: ast::DUMMY_NODE_ID };
|
let pat = Pat { node: pat, span: lo.to(self.prev_span), id: ast::DUMMY_NODE_ID };
|
||||||
let pat = self.maybe_recover_from_bad_qpath(pat)?;
|
let pat = self.maybe_recover_from_bad_qpath(pat, true)?;
|
||||||
|
|
||||||
Ok(P(pat))
|
Ok(P(pat))
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,11 +38,9 @@ type G = 'static + (Send)::AssocTy;
|
||||||
//~^ ERROR missing angle brackets in associated item path
|
//~^ ERROR missing angle brackets in associated item path
|
||||||
//~| ERROR ambiguous associated type
|
//~| ERROR ambiguous associated type
|
||||||
|
|
||||||
// FIXME
|
|
||||||
// This is actually a legal path with fn-like generic arguments in the middle!
|
// This is actually a legal path with fn-like generic arguments in the middle!
|
||||||
// Recovery should not apply in this context.
|
// Recovery should not apply in this context.
|
||||||
type H = Fn(u8) -> (u8)::Output;
|
type H = Fn(u8) -> (u8)::Output;
|
||||||
//~^ ERROR missing angle brackets in associated item path
|
//~^ ERROR ambiguous associated type
|
||||||
//~| ERROR ambiguous associated type
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -40,12 +40,6 @@ error: missing angle brackets in associated item path
|
||||||
37 | type G = 'static + (Send)::AssocTy;
|
37 | type G = 'static + (Send)::AssocTy;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<'static + Send>::AssocTy`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<'static + Send>::AssocTy`
|
||||||
|
|
||||||
error: missing angle brackets in associated item path
|
|
||||||
--> $DIR/bad-assoc-ty.rs:44:20
|
|
||||||
|
|
|
||||||
44 | type H = Fn(u8) -> (u8)::Output;
|
|
||||||
| ^^^^^^^^^^^^ help: try: `<(u8)>::Output`
|
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:11:10
|
--> $DIR/bad-assoc-ty.rs:11:10
|
||||||
|
|
|
|
||||||
|
@ -101,12 +95,12 @@ error[E0223]: ambiguous associated type
|
||||||
= note: specify the type using the syntax `<std::marker::Send + 'static as Trait>::AssocTy`
|
= note: specify the type using the syntax `<std::marker::Send + 'static as Trait>::AssocTy`
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:44:20
|
--> $DIR/bad-assoc-ty.rs:43:10
|
||||||
|
|
|
|
||||||
44 | type H = Fn(u8) -> (u8)::Output;
|
43 | type H = Fn(u8) -> (u8)::Output;
|
||||||
| ^^^^^^^^^^^^ ambiguous associated type
|
| ^^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
|
||||||
|
|
|
|
||||||
= note: specify the type using the syntax `<u8 as Trait>::Output`
|
= note: specify the type using the syntax `<std::ops::Fn(u8) -> u8 + 'static as Trait>::Output`
|
||||||
|
|
||||||
error: aborting due to 16 previous errors
|
error: aborting due to 15 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue