Make parse_seq_to_before_tokens take expected/nonexpected tokens, use in parse_precise_capturing_syntax
This commit is contained in:
parent
59e2c01c22
commit
68bd001c00
@ -1,7 +1,6 @@
|
|||||||
use super::pat::Expected;
|
use super::pat::Expected;
|
||||||
use super::{
|
use super::{
|
||||||
BlockMode, CommaRecoveryMode, Parser, PathStyle, Restrictions, SemiColonMode, SeqSep,
|
BlockMode, CommaRecoveryMode, Parser, PathStyle, Restrictions, SemiColonMode, SeqSep, TokenType,
|
||||||
TokenExpectType, TokenType,
|
|
||||||
};
|
};
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
AmbiguousPlus, AsyncMoveBlockIn2015, AttributeOnParamType, BadQPathStage2, BadTypePlus,
|
AmbiguousPlus, AsyncMoveBlockIn2015, AttributeOnParamType, BadQPathStage2, BadTypePlus,
|
||||||
@ -1045,9 +1044,7 @@ pub(super) fn recover_closure_body(
|
|||||||
/// passes through any errors encountered. Used for error recovery.
|
/// passes through any errors encountered. Used for error recovery.
|
||||||
pub(super) fn eat_to_tokens(&mut self, kets: &[&TokenKind]) {
|
pub(super) fn eat_to_tokens(&mut self, kets: &[&TokenKind]) {
|
||||||
if let Err(err) =
|
if let Err(err) =
|
||||||
self.parse_seq_to_before_tokens(kets, SeqSep::none(), TokenExpectType::Expect, |p| {
|
self.parse_seq_to_before_tokens(kets, &[], SeqSep::none(), |p| Ok(p.parse_token_tree()))
|
||||||
Ok(p.parse_token_tree())
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
err.cancel();
|
err.cancel();
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
|
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
|
||||||
use super::{
|
use super::{
|
||||||
AttrWrapper, BlockMode, ClosureSpans, ForceCollect, Parser, PathStyle, Restrictions,
|
AttrWrapper, BlockMode, ClosureSpans, ForceCollect, Parser, PathStyle, Restrictions,
|
||||||
SemiColonMode, SeqSep, TokenExpectType, TokenType, Trailing, TrailingToken,
|
SemiColonMode, SeqSep, TokenType, Trailing, TrailingToken,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
@ -2456,9 +2456,9 @@ fn parse_fn_block_decl(&mut self) -> PResult<'a, (P<FnDecl>, Span)> {
|
|||||||
self.expect(&token::BinOp(token::Or))?;
|
self.expect(&token::BinOp(token::Or))?;
|
||||||
let args = self
|
let args = self
|
||||||
.parse_seq_to_before_tokens(
|
.parse_seq_to_before_tokens(
|
||||||
&[&token::BinOp(token::Or), &token::OrOr],
|
&[&token::BinOp(token::Or)],
|
||||||
|
&[&token::OrOr],
|
||||||
SeqSep::trailing_allowed(token::Comma),
|
SeqSep::trailing_allowed(token::Comma),
|
||||||
TokenExpectType::NoExpect,
|
|
||||||
|p| p.parse_fn_block_param(),
|
|p| p.parse_fn_block_param(),
|
||||||
)?
|
)?
|
||||||
.0;
|
.0;
|
||||||
|
@ -335,18 +335,6 @@ fn to_string(&self) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Used by [`Parser::expect_any_with_type`].
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
enum TokenExpectType {
|
|
||||||
/// Unencountered tokens are inserted into [`Parser::expected_tokens`].
|
|
||||||
/// See [`Parser::check`].
|
|
||||||
Expect,
|
|
||||||
|
|
||||||
/// Unencountered tokens are not inserted into [`Parser::expected_tokens`].
|
|
||||||
/// See [`Parser::check_noexpect`].
|
|
||||||
NoExpect,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A sequence separator.
|
/// A sequence separator.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct SeqSep {
|
struct SeqSep {
|
||||||
@ -807,11 +795,13 @@ fn expect_gt(&mut self) -> PResult<'a, ()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the next token is contained within `kets`, and returns `true` if so.
|
/// Checks if the next token is contained within `kets`, and returns `true` if so.
|
||||||
fn expect_any_with_type(&mut self, kets: &[&TokenKind], expect: TokenExpectType) -> bool {
|
fn expect_any_with_type(
|
||||||
kets.iter().any(|k| match expect {
|
&mut self,
|
||||||
TokenExpectType::Expect => self.check(k),
|
kets_expected: &[&TokenKind],
|
||||||
TokenExpectType::NoExpect => self.check_noexpect(k),
|
kets_not_expected: &[&TokenKind],
|
||||||
})
|
) -> bool {
|
||||||
|
kets_expected.iter().any(|k| self.check(k))
|
||||||
|
|| kets_not_expected.iter().any(|k| self.check_noexpect(k))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a sequence until the specified delimiters. The function
|
/// Parses a sequence until the specified delimiters. The function
|
||||||
@ -819,9 +809,9 @@ fn expect_any_with_type(&mut self, kets: &[&TokenKind], expect: TokenExpectType)
|
|||||||
/// closing bracket.
|
/// closing bracket.
|
||||||
fn parse_seq_to_before_tokens<T>(
|
fn parse_seq_to_before_tokens<T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
kets: &[&TokenKind],
|
kets_expected: &[&TokenKind],
|
||||||
|
kets_not_expected: &[&TokenKind],
|
||||||
sep: SeqSep,
|
sep: SeqSep,
|
||||||
expect: TokenExpectType,
|
|
||||||
mut f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
|
mut f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
|
||||||
) -> PResult<'a, (ThinVec<T>, Trailing, Recovered)> {
|
) -> PResult<'a, (ThinVec<T>, Trailing, Recovered)> {
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
@ -829,7 +819,7 @@ fn parse_seq_to_before_tokens<T>(
|
|||||||
let mut trailing = Trailing::No;
|
let mut trailing = Trailing::No;
|
||||||
let mut v = ThinVec::new();
|
let mut v = ThinVec::new();
|
||||||
|
|
||||||
while !self.expect_any_with_type(kets, expect) {
|
while !self.expect_any_with_type(kets_expected, kets_not_expected) {
|
||||||
if let token::CloseDelim(..) | token::Eof = self.token.kind {
|
if let token::CloseDelim(..) | token::Eof = self.token.kind {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -927,7 +917,8 @@ fn parse_seq_to_before_tokens<T>(
|
|||||||
if self.token == token::Colon {
|
if self.token == token::Colon {
|
||||||
// we will try to recover in `maybe_recover_struct_lit_bad_delims`
|
// we will try to recover in `maybe_recover_struct_lit_bad_delims`
|
||||||
return Err(expect_err);
|
return Err(expect_err);
|
||||||
} else if let [token::CloseDelim(Delimiter::Parenthesis)] = kets
|
} else if let [token::CloseDelim(Delimiter::Parenthesis)] =
|
||||||
|
kets_expected
|
||||||
{
|
{
|
||||||
return Err(expect_err);
|
return Err(expect_err);
|
||||||
} else {
|
} else {
|
||||||
@ -940,7 +931,9 @@ fn parse_seq_to_before_tokens<T>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if sep.trailing_sep_allowed && self.expect_any_with_type(kets, expect) {
|
if sep.trailing_sep_allowed
|
||||||
|
&& self.expect_any_with_type(kets_expected, kets_not_expected)
|
||||||
|
{
|
||||||
trailing = Trailing::Yes;
|
trailing = Trailing::Yes;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1020,7 +1013,7 @@ fn parse_seq_to_before_end<T>(
|
|||||||
sep: SeqSep,
|
sep: SeqSep,
|
||||||
f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
|
f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
|
||||||
) -> PResult<'a, (ThinVec<T>, Trailing, Recovered)> {
|
) -> PResult<'a, (ThinVec<T>, Trailing, Recovered)> {
|
||||||
self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f)
|
self.parse_seq_to_before_tokens(&[ket], &[], sep, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a sequence, including only the closing delimiter. The function
|
/// Parses a sequence, including only the closing delimiter. The function
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
|
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
|
||||||
|
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
use rustc_ast::token::{self, BinOpToken, Delimiter, Token, TokenKind};
|
||||||
use rustc_ast::util::case::Case;
|
use rustc_ast::util::case::Case;
|
||||||
use rustc_ast::{
|
use rustc_ast::{
|
||||||
self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, FnRetTy, GenericBound,
|
self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, FnRetTy, GenericBound,
|
||||||
@ -694,9 +694,14 @@ fn parse_precise_capturing_args(
|
|||||||
&mut self,
|
&mut self,
|
||||||
) -> PResult<'a, (ThinVec<PreciseCapturingArg>, Span)> {
|
) -> PResult<'a, (ThinVec<PreciseCapturingArg>, Span)> {
|
||||||
let lo = self.token.span;
|
let lo = self.token.span;
|
||||||
let (args, _) = self.parse_unspanned_seq(
|
self.expect_lt()?;
|
||||||
&TokenKind::Lt,
|
let (args, _, _) = self.parse_seq_to_before_tokens(
|
||||||
&TokenKind::Gt,
|
&[&TokenKind::Gt],
|
||||||
|
&[
|
||||||
|
&TokenKind::Ge,
|
||||||
|
&TokenKind::BinOp(BinOpToken::Shr),
|
||||||
|
&TokenKind::BinOpEq(BinOpToken::Shr),
|
||||||
|
],
|
||||||
SeqSep::trailing_allowed(token::Comma),
|
SeqSep::trailing_allowed(token::Comma),
|
||||||
|self_| {
|
|self_| {
|
||||||
if self_.check_keyword(kw::SelfUpper) {
|
if self_.check_keyword(kw::SelfUpper) {
|
||||||
@ -717,6 +722,7 @@ fn parse_precise_capturing_args(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
self.expect_gt()?;
|
||||||
Ok((args, lo.to(self.prev_token.span)))
|
Ok((args, lo.to(self.prev_token.span)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,5 @@
|
|||||||
|
|
||||||
fn hello() -> impl use<'a {}> Sized {}
|
fn hello() -> impl use<'a {}> Sized {}
|
||||||
//~^ ERROR expected one of `,` or `>`, found `{`
|
//~^ ERROR expected one of `,` or `>`, found `{`
|
||||||
//~| ERROR expected item, found `>`
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -4,13 +4,5 @@ error: expected one of `,` or `>`, found `{`
|
|||||||
LL | fn hello() -> impl use<'a {}> Sized {}
|
LL | fn hello() -> impl use<'a {}> Sized {}
|
||||||
| ^ expected one of `,` or `>`
|
| ^ expected one of `,` or `>`
|
||||||
|
|
||||||
error: expected item, found `>`
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/unexpected-token.rs:5:29
|
|
||||||
|
|
|
||||||
LL | fn hello() -> impl use<'a {}> Sized {}
|
|
||||||
| ^ expected item
|
|
||||||
|
|
|
||||||
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
fn a() {
|
fn a() {
|
||||||
[0; [|_: _ &_| ()].len()]
|
[0; [|_: _ &_| ()].len()]
|
||||||
//~^ ERROR expected `,`, found `&`
|
//~^ ERROR expected one of `,` or `|`, found `&`
|
||||||
//~| ERROR type annotations needed
|
//~| ERROR type annotations needed
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ fn b() {
|
|||||||
|
|
||||||
fn c() {
|
fn c() {
|
||||||
[0; [|&_: _ &_| {}; 0 ].len()]
|
[0; [|&_: _ &_| {}; 0 ].len()]
|
||||||
//~^ ERROR expected `,`, found `&`
|
//~^ ERROR expected one of `,` or `|`, found `&`
|
||||||
//~| ERROR type annotations needed
|
//~| ERROR type annotations needed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: expected `,`, found `&`
|
error: expected one of `,` or `|`, found `&`
|
||||||
--> $DIR/issue-66706.rs:2:16
|
--> $DIR/issue-66706.rs:2:16
|
||||||
|
|
|
|
||||||
LL | [0; [|_: _ &_| ()].len()]
|
LL | [0; [|_: _ &_| ()].len()]
|
||||||
| -^ expected `,`
|
| -^ expected one of `,` or `|`
|
||||||
| |
|
| |
|
||||||
| help: missing `,`
|
| help: missing `,`
|
||||||
|
|
||||||
@ -12,11 +12,11 @@ error: expected identifier, found reserved identifier `_`
|
|||||||
LL | [0; [|f @ &ref _| {} ; 0 ].len() ];
|
LL | [0; [|f @ &ref _| {} ; 0 ].len() ];
|
||||||
| ^ expected identifier, found reserved identifier
|
| ^ expected identifier, found reserved identifier
|
||||||
|
|
||||||
error: expected `,`, found `&`
|
error: expected one of `,` or `|`, found `&`
|
||||||
--> $DIR/issue-66706.rs:13:17
|
--> $DIR/issue-66706.rs:13:17
|
||||||
|
|
|
|
||||||
LL | [0; [|&_: _ &_| {}; 0 ].len()]
|
LL | [0; [|&_: _ &_| {}; 0 ].len()]
|
||||||
| -^ expected `,`
|
| -^ expected one of `,` or `|`
|
||||||
| |
|
| |
|
||||||
| help: missing `,`
|
| help: missing `,`
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user