mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-04 14:07:36 +00:00
extract parse_ty_tuple_or_parens
This commit is contained in:
parent
c64eecf4d0
commit
f3ef4a416d
@ -74,44 +74,7 @@ impl<'a> Parser<'a> {
|
|||||||
let lo = self.token.span;
|
let lo = self.token.span;
|
||||||
let mut impl_dyn_multi = false;
|
let mut impl_dyn_multi = false;
|
||||||
let kind = if self.eat(&token::OpenDelim(token::Paren)) {
|
let kind = if self.eat(&token::OpenDelim(token::Paren)) {
|
||||||
// `(TYPE)` is a parenthesized type.
|
self.parse_ty_tuple_or_parens(allow_plus)?
|
||||||
// `(TYPE,)` is a tuple with a single field of type TYPE.
|
|
||||||
let mut ts = vec![];
|
|
||||||
let mut last_comma = false;
|
|
||||||
while self.token != token::CloseDelim(token::Paren) {
|
|
||||||
ts.push(self.parse_ty()?);
|
|
||||||
if self.eat(&token::Comma) {
|
|
||||||
last_comma = true;
|
|
||||||
} else {
|
|
||||||
last_comma = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let trailing_plus = self.prev_token_kind == PrevTokenKind::Plus;
|
|
||||||
self.expect(&token::CloseDelim(token::Paren))?;
|
|
||||||
|
|
||||||
if ts.len() == 1 && !last_comma {
|
|
||||||
let ty = ts.into_iter().nth(0).unwrap().into_inner();
|
|
||||||
let maybe_bounds = allow_plus && self.token.is_like_plus();
|
|
||||||
match ty.kind {
|
|
||||||
// `(TY_BOUND_NOPAREN) + BOUND + ...`.
|
|
||||||
TyKind::Path(None, ref path) if maybe_bounds => {
|
|
||||||
self.parse_remaining_bounds(Vec::new(), path.clone(), lo, true)?
|
|
||||||
}
|
|
||||||
TyKind::TraitObject(ref bounds, TraitObjectSyntax::None)
|
|
||||||
if maybe_bounds && bounds.len() == 1 && !trailing_plus => {
|
|
||||||
let path = match bounds[0] {
|
|
||||||
GenericBound::Trait(ref pt, ..) => pt.trait_ref.path.clone(),
|
|
||||||
GenericBound::Outlives(..) => self.bug("unexpected lifetime bound"),
|
|
||||||
};
|
|
||||||
self.parse_remaining_bounds(Vec::new(), path, lo, true)?
|
|
||||||
}
|
|
||||||
// `(TYPE)`
|
|
||||||
_ => TyKind::Paren(P(ty))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
TyKind::Tup(ts)
|
|
||||||
}
|
|
||||||
} else if self.eat(&token::Not) {
|
} else if self.eat(&token::Not) {
|
||||||
// Never type `!`
|
// Never type `!`
|
||||||
TyKind::Never
|
TyKind::Never
|
||||||
@ -242,6 +205,49 @@ impl<'a> Parser<'a> {
|
|||||||
self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery)
|
self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses either:
|
||||||
|
/// - `(TYPE)`, a parenthesized type.
|
||||||
|
/// - `(TYPE,)`, a tuple with a single field of type TYPE.
|
||||||
|
fn parse_ty_tuple_or_parens(&mut self, allow_plus: bool) -> PResult<'a, TyKind> {
|
||||||
|
let lo = self.token.span;
|
||||||
|
let mut ts = vec![];
|
||||||
|
let mut last_comma = false;
|
||||||
|
while self.token != token::CloseDelim(token::Paren) {
|
||||||
|
ts.push(self.parse_ty()?);
|
||||||
|
if self.eat(&token::Comma) {
|
||||||
|
last_comma = true;
|
||||||
|
} else {
|
||||||
|
last_comma = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let trailing_plus = self.prev_token_kind == PrevTokenKind::Plus;
|
||||||
|
self.expect(&token::CloseDelim(token::Paren))?;
|
||||||
|
|
||||||
|
if ts.len() == 1 && !last_comma {
|
||||||
|
let ty = ts.into_iter().nth(0).unwrap().into_inner();
|
||||||
|
let maybe_bounds = allow_plus && self.token.is_like_plus();
|
||||||
|
match ty.kind {
|
||||||
|
// `(TY_BOUND_NOPAREN) + BOUND + ...`.
|
||||||
|
TyKind::Path(None, ref path) if maybe_bounds => {
|
||||||
|
self.parse_remaining_bounds(Vec::new(), path.clone(), lo, true)
|
||||||
|
}
|
||||||
|
TyKind::TraitObject(ref bounds, TraitObjectSyntax::None)
|
||||||
|
if maybe_bounds && bounds.len() == 1 && !trailing_plus => {
|
||||||
|
let path = match bounds[0] {
|
||||||
|
GenericBound::Trait(ref pt, ..) => pt.trait_ref.path.clone(),
|
||||||
|
GenericBound::Outlives(..) => self.bug("unexpected lifetime bound"),
|
||||||
|
};
|
||||||
|
self.parse_remaining_bounds(Vec::new(), path, lo, true)
|
||||||
|
}
|
||||||
|
// `(TYPE)`
|
||||||
|
_ => Ok(TyKind::Paren(P(ty)))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(TyKind::Tup(ts))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_remaining_bounds(&mut self, generic_params: Vec<GenericParam>, path: ast::Path,
|
fn parse_remaining_bounds(&mut self, generic_params: Vec<GenericParam>, path: ast::Path,
|
||||||
lo: Span, parse_plus: bool) -> PResult<'a, TyKind> {
|
lo: Span, parse_plus: bool) -> PResult<'a, TyKind> {
|
||||||
let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span));
|
let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span));
|
||||||
|
Loading…
Reference in New Issue
Block a user