parse_ty_common: use enum
s instead of bool
s.
This commit is contained in:
parent
c9290dceee
commit
c0b7b41cff
@ -1,3 +1,4 @@
|
|||||||
|
use super::ty::AllowPlus;
|
||||||
use super::{BlockMode, Parser, PathStyle, SemiColonMode, SeqSep, TokenExpectType, TokenType};
|
use super::{BlockMode, Parser, PathStyle, SemiColonMode, SeqSep, TokenExpectType, TokenType};
|
||||||
|
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
@ -693,11 +694,11 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
pub(super) fn maybe_report_ambiguous_plus(
|
pub(super) fn maybe_report_ambiguous_plus(
|
||||||
&mut self,
|
&mut self,
|
||||||
allow_plus: bool,
|
allow_plus: AllowPlus,
|
||||||
impl_dyn_multi: bool,
|
impl_dyn_multi: bool,
|
||||||
ty: &Ty,
|
ty: &Ty,
|
||||||
) {
|
) {
|
||||||
if !allow_plus && impl_dyn_multi {
|
if matches!(allow_plus, AllowPlus::No) && impl_dyn_multi {
|
||||||
let sum_with_parens = format!("({})", pprust::ty_to_string(&ty));
|
let sum_with_parens = format!("({})", pprust::ty_to_string(&ty));
|
||||||
self.struct_span_err(ty.span, "ambiguous `+` in a type")
|
self.struct_span_err(ty.span, "ambiguous `+` in a type")
|
||||||
.span_suggestion(
|
.span_suggestion(
|
||||||
@ -712,11 +713,11 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
pub(super) fn maybe_recover_from_bad_type_plus(
|
pub(super) fn maybe_recover_from_bad_type_plus(
|
||||||
&mut self,
|
&mut self,
|
||||||
allow_plus: bool,
|
allow_plus: AllowPlus,
|
||||||
ty: &Ty,
|
ty: &Ty,
|
||||||
) -> PResult<'a, ()> {
|
) -> PResult<'a, ()> {
|
||||||
// Do not add `+` to expected tokens.
|
// Do not add `+` to expected tokens.
|
||||||
if !allow_plus || !self.token.is_like_plus() {
|
if matches!(allow_plus, AllowPlus::No) || !self.token.is_like_plus() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::pat::{GateOr, PARAM_EXPECTED};
|
use super::pat::{GateOr, PARAM_EXPECTED};
|
||||||
|
use super::ty::{AllowPlus, RecoverQPath};
|
||||||
use super::{BlockMode, Parser, PathStyle, PrevTokenKind, Restrictions, TokenType};
|
use super::{BlockMode, Parser, PathStyle, PrevTokenKind, Restrictions, TokenType};
|
||||||
use super::{SemiColonMode, SeqSep, TokenExpectType};
|
use super::{SemiColonMode, SeqSep, TokenExpectType};
|
||||||
use crate::maybe_recover_from_interpolated_ty_qpath;
|
use crate::maybe_recover_from_interpolated_ty_qpath;
|
||||||
@ -1399,7 +1400,7 @@ impl<'a> Parser<'a> {
|
|||||||
self.expect_or()?;
|
self.expect_or()?;
|
||||||
args
|
args
|
||||||
};
|
};
|
||||||
let output = self.parse_ret_ty(true, true)?;
|
let output = self.parse_ret_ty(AllowPlus::Yes, RecoverQPath::Yes)?;
|
||||||
|
|
||||||
Ok(P(FnDecl { inputs, output }))
|
Ok(P(FnDecl { inputs, output }))
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error};
|
use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error};
|
||||||
|
use super::ty::{AllowPlus, RecoverQPath};
|
||||||
use super::{FollowedByType, Parser, PathStyle};
|
use super::{FollowedByType, Parser, PathStyle};
|
||||||
|
|
||||||
use crate::maybe_whole;
|
use crate::maybe_whole;
|
||||||
@ -1839,7 +1840,7 @@ impl<'a> Parser<'a> {
|
|||||||
fn parse_fn_sig(&mut self, cfg: &ParamCfg) -> PResult<'a, (Ident, P<FnDecl>, Generics)> {
|
fn parse_fn_sig(&mut self, cfg: &ParamCfg) -> PResult<'a, (Ident, P<FnDecl>, Generics)> {
|
||||||
let ident = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
let mut generics = self.parse_generics()?;
|
let mut generics = self.parse_generics()?;
|
||||||
let decl = self.parse_fn_decl(cfg, true)?;
|
let decl = self.parse_fn_decl(cfg, AllowPlus::Yes)?;
|
||||||
generics.where_clause = self.parse_where_clause()?;
|
generics.where_clause = self.parse_where_clause()?;
|
||||||
Ok((ident, decl, generics))
|
Ok((ident, decl, generics))
|
||||||
}
|
}
|
||||||
@ -1848,11 +1849,11 @@ impl<'a> Parser<'a> {
|
|||||||
pub(super) fn parse_fn_decl(
|
pub(super) fn parse_fn_decl(
|
||||||
&mut self,
|
&mut self,
|
||||||
cfg: &ParamCfg,
|
cfg: &ParamCfg,
|
||||||
ret_allow_plus: bool,
|
ret_allow_plus: AllowPlus,
|
||||||
) -> PResult<'a, P<FnDecl>> {
|
) -> PResult<'a, P<FnDecl>> {
|
||||||
Ok(P(FnDecl {
|
Ok(P(FnDecl {
|
||||||
inputs: self.parse_fn_params(cfg)?,
|
inputs: self.parse_fn_params(cfg)?,
|
||||||
output: self.parse_ret_ty(ret_allow_plus, true)?,
|
output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes)?,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use super::ty::{AllowPlus, RecoverQPath};
|
||||||
use super::{Parser, TokenType};
|
use super::{Parser, TokenType};
|
||||||
use crate::maybe_whole;
|
use crate::maybe_whole;
|
||||||
use rustc_errors::{pluralize, Applicability, PResult};
|
use rustc_errors::{pluralize, Applicability, PResult};
|
||||||
@ -224,7 +225,7 @@ impl<'a> Parser<'a> {
|
|||||||
// `(T, U) -> R`
|
// `(T, U) -> R`
|
||||||
let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?;
|
let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?;
|
||||||
let span = ident.span.to(self.prev_span);
|
let span = ident.span.to(self.prev_span);
|
||||||
let output = self.parse_ret_ty(false, false)?;
|
let output = self.parse_ret_ty(AllowPlus::No, RecoverQPath::No)?;
|
||||||
ParenthesizedArgs { inputs, output, span }.into()
|
ParenthesizedArgs { inputs, output, span }.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,6 +36,23 @@ impl BoundModifiers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub(super) enum AllowPlus {
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) enum RecoverQPath {
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is `...` (`CVarArgs`) legal at this level of type parsing?
|
||||||
|
enum AllowCVariadic {
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`,
|
/// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`,
|
||||||
/// `IDENT<<u8 as Trait>::AssocTy>`.
|
/// `IDENT<<u8 as Trait>::AssocTy>`.
|
||||||
///
|
///
|
||||||
@ -48,14 +65,14 @@ fn can_continue_type_after_non_fn_ident(t: &Token) -> bool {
|
|||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
/// Parses a type.
|
/// Parses 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, true, false)
|
self.parse_ty_common(AllowPlus::Yes, RecoverQPath::Yes, AllowCVariadic::No)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a type suitable for a function or function pointer parameter.
|
/// Parse a type suitable for a function or function pointer parameter.
|
||||||
/// The difference from `parse_ty` is that this version allows `...`
|
/// The difference from `parse_ty` is that this version allows `...`
|
||||||
/// (`CVarArgs`) at the top level of the the type.
|
/// (`CVarArgs`) at the top level of the the type.
|
||||||
pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>> {
|
pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>> {
|
||||||
self.parse_ty_common(true, true, true)
|
self.parse_ty_common(AllowPlus::Yes, RecoverQPath::Yes, AllowCVariadic::Yes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a type in restricted contexts where `+` is not permitted.
|
/// Parses a type in restricted contexts where `+` is not permitted.
|
||||||
@ -65,18 +82,19 @@ 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.
|
||||||
pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
|
pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
|
||||||
self.parse_ty_common(false, true, false)
|
self.parse_ty_common(AllowPlus::No, RecoverQPath::Yes, AllowCVariadic::No)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses an optional return type `[ -> TY ]` in a function declaration.
|
/// Parses an optional return type `[ -> TY ]` in a function declaration.
|
||||||
pub(super) fn parse_ret_ty(
|
pub(super) fn parse_ret_ty(
|
||||||
&mut self,
|
&mut self,
|
||||||
allow_plus: bool,
|
allow_plus: AllowPlus,
|
||||||
allow_qpath_recovery: bool,
|
recover_qpath: RecoverQPath,
|
||||||
) -> PResult<'a, FunctionRetTy> {
|
) -> PResult<'a, FunctionRetTy> {
|
||||||
Ok(if self.eat(&token::RArrow) {
|
Ok(if self.eat(&token::RArrow) {
|
||||||
// FIXME(Centril): Can we unconditionally `allow_plus`?
|
// FIXME(Centril): Can we unconditionally `allow_plus`?
|
||||||
FunctionRetTy::Ty(self.parse_ty_common(allow_plus, allow_qpath_recovery, false)?)
|
let ty = self.parse_ty_common(allow_plus, recover_qpath, AllowCVariadic::No)?;
|
||||||
|
FunctionRetTy::Ty(ty)
|
||||||
} else {
|
} else {
|
||||||
FunctionRetTy::Default(self.token.span.shrink_to_lo())
|
FunctionRetTy::Default(self.token.span.shrink_to_lo())
|
||||||
})
|
})
|
||||||
@ -84,11 +102,11 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
fn parse_ty_common(
|
fn parse_ty_common(
|
||||||
&mut self,
|
&mut self,
|
||||||
allow_plus: bool,
|
allow_plus: AllowPlus,
|
||||||
allow_qpath_recovery: bool,
|
recover_qpath: RecoverQPath,
|
||||||
// Is `...` (`CVarArgs`) legal in the immediate top level call?
|
allow_c_variadic: AllowCVariadic,
|
||||||
allow_c_variadic: bool,
|
|
||||||
) -> PResult<'a, P<Ty>> {
|
) -> PResult<'a, P<Ty>> {
|
||||||
|
let allow_qpath_recovery = matches!(recover_qpath, RecoverQPath::Yes);
|
||||||
maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
|
maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
|
||||||
maybe_whole!(self, NtTy, |x| x);
|
maybe_whole!(self, NtTy, |x| x);
|
||||||
|
|
||||||
@ -124,7 +142,7 @@ impl<'a> Parser<'a> {
|
|||||||
self.parse_ty_bare_fn(lifetime_defs)?
|
self.parse_ty_bare_fn(lifetime_defs)?
|
||||||
} else {
|
} else {
|
||||||
let path = self.parse_path(PathStyle::Type)?;
|
let path = self.parse_path(PathStyle::Type)?;
|
||||||
let parse_plus = allow_plus && self.check_plus();
|
let parse_plus = matches!(allow_plus, AllowPlus::Yes) && self.check_plus();
|
||||||
self.parse_remaining_bounds(lifetime_defs, path, lo, parse_plus)?
|
self.parse_remaining_bounds(lifetime_defs, path, lo, parse_plus)?
|
||||||
}
|
}
|
||||||
} else if self.eat_keyword(kw::Impl) {
|
} else if self.eat_keyword(kw::Impl) {
|
||||||
@ -144,7 +162,7 @@ impl<'a> Parser<'a> {
|
|||||||
} else if self.token.is_path_start() {
|
} else if self.token.is_path_start() {
|
||||||
self.parse_path_start_ty(lo, allow_plus)?
|
self.parse_path_start_ty(lo, allow_plus)?
|
||||||
} else if self.eat(&token::DotDotDot) {
|
} else if self.eat(&token::DotDotDot) {
|
||||||
if allow_c_variadic {
|
if let AllowCVariadic::Yes = allow_c_variadic {
|
||||||
TyKind::CVarArgs
|
TyKind::CVarArgs
|
||||||
} else {
|
} else {
|
||||||
// FIXME(Centril): Should we just allow `...` syntactically
|
// FIXME(Centril): Should we just allow `...` syntactically
|
||||||
@ -172,7 +190,7 @@ impl<'a> Parser<'a> {
|
|||||||
/// Parses either:
|
/// Parses either:
|
||||||
/// - `(TYPE)`, a parenthesized type.
|
/// - `(TYPE)`, a parenthesized type.
|
||||||
/// - `(TYPE,)`, a tuple with a single field of type TYPE.
|
/// - `(TYPE,)`, a tuple with a single field of type TYPE.
|
||||||
fn parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: bool) -> PResult<'a, TyKind> {
|
fn parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
|
||||||
let mut trailing_plus = false;
|
let mut trailing_plus = false;
|
||||||
let (ts, trailing) = self.parse_paren_comma_seq(|p| {
|
let (ts, trailing) = self.parse_paren_comma_seq(|p| {
|
||||||
let ty = p.parse_ty()?;
|
let ty = p.parse_ty()?;
|
||||||
@ -182,7 +200,7 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
if ts.len() == 1 && !trailing {
|
if ts.len() == 1 && !trailing {
|
||||||
let ty = ts.into_iter().nth(0).unwrap().into_inner();
|
let ty = ts.into_iter().nth(0).unwrap().into_inner();
|
||||||
let maybe_bounds = allow_plus && self.token.is_like_plus();
|
let maybe_bounds = matches!(allow_plus, AllowPlus::Yes) && self.token.is_like_plus();
|
||||||
match ty.kind {
|
match ty.kind {
|
||||||
// `(TY_BOUND_NOPAREN) + BOUND + ...`.
|
// `(TY_BOUND_NOPAREN) + BOUND + ...`.
|
||||||
TyKind::Path(None, path) if maybe_bounds => {
|
TyKind::Path(None, path) if maybe_bounds => {
|
||||||
@ -288,7 +306,8 @@ impl<'a> Parser<'a> {
|
|||||||
let unsafety = self.parse_unsafety();
|
let unsafety = self.parse_unsafety();
|
||||||
let ext = self.parse_extern()?;
|
let ext = self.parse_extern()?;
|
||||||
self.expect_keyword(kw::Fn)?;
|
self.expect_keyword(kw::Fn)?;
|
||||||
let decl = self.parse_fn_decl(&ParamCfg { is_name_required: |_| false }, false)?;
|
let cfg = ParamCfg { is_name_required: |_| false };
|
||||||
|
let decl = self.parse_fn_decl(&cfg, AllowPlus::No)?;
|
||||||
Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params, decl })))
|
Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params, decl })))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +345,7 @@ impl<'a> Parser<'a> {
|
|||||||
/// 1. a type macro, `mac!(...)`,
|
/// 1. a type macro, `mac!(...)`,
|
||||||
/// 2. a bare trait object, `B0 + ... + Bn`,
|
/// 2. a bare trait object, `B0 + ... + Bn`,
|
||||||
/// 3. or a path, `path::to::MyType`.
|
/// 3. or a path, `path::to::MyType`.
|
||||||
fn parse_path_start_ty(&mut self, lo: Span, allow_plus: bool) -> PResult<'a, TyKind> {
|
fn parse_path_start_ty(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
|
||||||
// Simple path
|
// Simple path
|
||||||
let path = self.parse_path(PathStyle::Type)?;
|
let path = self.parse_path(PathStyle::Type)?;
|
||||||
if self.eat(&token::Not) {
|
if self.eat(&token::Not) {
|
||||||
@ -336,7 +355,7 @@ impl<'a> Parser<'a> {
|
|||||||
args: self.parse_mac_args()?,
|
args: self.parse_mac_args()?,
|
||||||
prior_type_ascription: self.last_type_ascription,
|
prior_type_ascription: self.last_type_ascription,
|
||||||
}))
|
}))
|
||||||
} else if allow_plus && self.check_plus() {
|
} else if matches!(allow_plus, AllowPlus::Yes) && self.check_plus() {
|
||||||
// `Trait1 + Trait2 + 'a`
|
// `Trait1 + Trait2 + 'a`
|
||||||
self.parse_remaining_bounds(Vec::new(), path, lo, true)
|
self.parse_remaining_bounds(Vec::new(), path, lo, true)
|
||||||
} else {
|
} else {
|
||||||
@ -359,7 +378,7 @@ impl<'a> Parser<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
colon_span: Option<Span>,
|
colon_span: Option<Span>,
|
||||||
) -> PResult<'a, GenericBounds> {
|
) -> PResult<'a, GenericBounds> {
|
||||||
self.parse_generic_bounds_common(true, colon_span)
|
self.parse_generic_bounds_common(AllowPlus::Yes, colon_span)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`.
|
/// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`.
|
||||||
@ -367,7 +386,7 @@ impl<'a> Parser<'a> {
|
|||||||
/// See `parse_generic_bound` for the `BOUND` grammar.
|
/// See `parse_generic_bound` for the `BOUND` grammar.
|
||||||
fn parse_generic_bounds_common(
|
fn parse_generic_bounds_common(
|
||||||
&mut self,
|
&mut self,
|
||||||
allow_plus: bool,
|
allow_plus: AllowPlus,
|
||||||
colon_span: Option<Span>,
|
colon_span: Option<Span>,
|
||||||
) -> PResult<'a, GenericBounds> {
|
) -> PResult<'a, GenericBounds> {
|
||||||
let mut bounds = Vec::new();
|
let mut bounds = Vec::new();
|
||||||
@ -377,7 +396,7 @@ impl<'a> Parser<'a> {
|
|||||||
Ok(bound) => bounds.push(bound),
|
Ok(bound) => bounds.push(bound),
|
||||||
Err(neg_sp) => negative_bounds.push(neg_sp),
|
Err(neg_sp) => negative_bounds.push(neg_sp),
|
||||||
}
|
}
|
||||||
if !allow_plus || !self.eat_plus() {
|
if matches!(allow_plus, AllowPlus::No) || !self.eat_plus() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user