Gate some recovery behind a flag
Mainly in `expr.rs`
This commit is contained in:
parent
5237c4d83d
commit
29e50e8d35
3 changed files with 32 additions and 6 deletions
|
@ -769,6 +769,10 @@ impl<'a> Parser<'a> {
|
||||||
segment: &PathSegment,
|
segment: &PathSegment,
|
||||||
end: &[&TokenKind],
|
end: &[&TokenKind],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
if !self.may_recover() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// This function is intended to be invoked after parsing a path segment where there are two
|
// This function is intended to be invoked after parsing a path segment where there are two
|
||||||
// cases:
|
// cases:
|
||||||
//
|
//
|
||||||
|
@ -863,6 +867,10 @@ impl<'a> Parser<'a> {
|
||||||
/// Check if a method call with an intended turbofish has been written without surrounding
|
/// Check if a method call with an intended turbofish has been written without surrounding
|
||||||
/// angle brackets.
|
/// angle brackets.
|
||||||
pub(super) fn check_turbofish_missing_angle_brackets(&mut self, segment: &mut PathSegment) {
|
pub(super) fn check_turbofish_missing_angle_brackets(&mut self, segment: &mut PathSegment) {
|
||||||
|
if !self.may_recover() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if token::ModSep == self.token.kind && segment.args.is_none() {
|
if token::ModSep == self.token.kind && segment.args.is_none() {
|
||||||
let snapshot = self.create_snapshot_for_diagnostic();
|
let snapshot = self.create_snapshot_for_diagnostic();
|
||||||
self.bump();
|
self.bump();
|
||||||
|
@ -1396,6 +1404,10 @@ impl<'a> Parser<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
base: P<T>,
|
base: P<T>,
|
||||||
) -> PResult<'a, P<T>> {
|
) -> PResult<'a, P<T>> {
|
||||||
|
if !self.may_recover() {
|
||||||
|
return Ok(base);
|
||||||
|
}
|
||||||
|
|
||||||
// Do not add `::` to expected tokens.
|
// Do not add `::` to expected tokens.
|
||||||
if self.token == token::ModSep {
|
if self.token == token::ModSep {
|
||||||
if let Some(ty) = base.to_ty() {
|
if let Some(ty) = base.to_ty() {
|
||||||
|
|
|
@ -132,7 +132,7 @@ impl<'a> Parser<'a> {
|
||||||
Ok(expr) => Ok(expr),
|
Ok(expr) => Ok(expr),
|
||||||
Err(mut err) => match self.token.ident() {
|
Err(mut err) => match self.token.ident() {
|
||||||
Some((Ident { name: kw::Underscore, .. }, false))
|
Some((Ident { name: kw::Underscore, .. }, false))
|
||||||
if self.look_ahead(1, |t| t == &token::Comma) =>
|
if self.may_recover() && self.look_ahead(1, |t| t == &token::Comma) =>
|
||||||
{
|
{
|
||||||
// Special-case handling of `foo(_, _, _)`
|
// Special-case handling of `foo(_, _, _)`
|
||||||
err.emit();
|
err.emit();
|
||||||
|
@ -456,7 +456,7 @@ impl<'a> Parser<'a> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
(Some(op), _) => (op, self.token.span),
|
(Some(op), _) => (op, self.token.span),
|
||||||
(None, Some((Ident { name: sym::and, span }, false))) => {
|
(None, Some((Ident { name: sym::and, span }, false))) if self.may_recover() => {
|
||||||
self.sess.emit_err(InvalidLogicalOperator {
|
self.sess.emit_err(InvalidLogicalOperator {
|
||||||
span: self.token.span,
|
span: self.token.span,
|
||||||
incorrect: "and".into(),
|
incorrect: "and".into(),
|
||||||
|
@ -464,7 +464,7 @@ impl<'a> Parser<'a> {
|
||||||
});
|
});
|
||||||
(AssocOp::LAnd, span)
|
(AssocOp::LAnd, span)
|
||||||
}
|
}
|
||||||
(None, Some((Ident { name: sym::or, span }, false))) => {
|
(None, Some((Ident { name: sym::or, span }, false))) if self.may_recover() => {
|
||||||
self.sess.emit_err(InvalidLogicalOperator {
|
self.sess.emit_err(InvalidLogicalOperator {
|
||||||
span: self.token.span,
|
span: self.token.span,
|
||||||
incorrect: "or".into(),
|
incorrect: "or".into(),
|
||||||
|
@ -615,7 +615,7 @@ impl<'a> Parser<'a> {
|
||||||
token::Ident(..) if this.token.is_keyword(kw::Box) => {
|
token::Ident(..) if this.token.is_keyword(kw::Box) => {
|
||||||
make_it!(this, attrs, |this, _| this.parse_box_expr(lo))
|
make_it!(this, attrs, |this, _| this.parse_box_expr(lo))
|
||||||
}
|
}
|
||||||
token::Ident(..) if this.is_mistaken_not_ident_negation() => {
|
token::Ident(..) if this.may_recover() && this.is_mistaken_not_ident_negation() => {
|
||||||
make_it!(this, attrs, |this, _| this.recover_not_expr(lo))
|
make_it!(this, attrs, |this, _| this.recover_not_expr(lo))
|
||||||
}
|
}
|
||||||
_ => return this.parse_dot_or_call_expr(Some(attrs)),
|
_ => return this.parse_dot_or_call_expr(Some(attrs)),
|
||||||
|
@ -718,6 +718,10 @@ impl<'a> Parser<'a> {
|
||||||
let cast_expr = match self.parse_as_cast_ty() {
|
let cast_expr = match self.parse_as_cast_ty() {
|
||||||
Ok(rhs) => mk_expr(self, lhs, rhs),
|
Ok(rhs) => mk_expr(self, lhs, rhs),
|
||||||
Err(type_err) => {
|
Err(type_err) => {
|
||||||
|
if !self.may_recover() {
|
||||||
|
return Err(type_err);
|
||||||
|
}
|
||||||
|
|
||||||
// Rewind to before attempting to parse the type with generics, to recover
|
// Rewind to before attempting to parse the type with generics, to recover
|
||||||
// from situations like `x as usize < y` in which we first tried to parse
|
// from situations like `x as usize < y` in which we first tried to parse
|
||||||
// `usize < y` as a type with generic arguments.
|
// `usize < y` as a type with generic arguments.
|
||||||
|
@ -1197,6 +1201,10 @@ impl<'a> Parser<'a> {
|
||||||
seq: &mut PResult<'a, P<Expr>>,
|
seq: &mut PResult<'a, P<Expr>>,
|
||||||
snapshot: Option<(SnapshotParser<'a>, ExprKind)>,
|
snapshot: Option<(SnapshotParser<'a>, ExprKind)>,
|
||||||
) -> Option<P<Expr>> {
|
) -> Option<P<Expr>> {
|
||||||
|
if !self.may_recover() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
match (seq.as_mut(), snapshot) {
|
match (seq.as_mut(), snapshot) {
|
||||||
(Err(err), Some((mut snapshot, ExprKind::Path(None, path)))) => {
|
(Err(err), Some((mut snapshot, ExprKind::Path(None, path)))) => {
|
||||||
snapshot.bump(); // `(`
|
snapshot.bump(); // `(`
|
||||||
|
@ -1360,7 +1368,7 @@ impl<'a> Parser<'a> {
|
||||||
)
|
)
|
||||||
} else if self.check_inline_const(0) {
|
} else if self.check_inline_const(0) {
|
||||||
self.parse_const_block(lo.to(self.token.span), false)
|
self.parse_const_block(lo.to(self.token.span), false)
|
||||||
} else if self.is_do_catch_block() {
|
} else if self.may_recover() && self.is_do_catch_block() {
|
||||||
self.recover_do_catch()
|
self.recover_do_catch()
|
||||||
} else if self.is_try_block() {
|
} else if self.is_try_block() {
|
||||||
self.expect_keyword(kw::Try)?;
|
self.expect_keyword(kw::Try)?;
|
||||||
|
@ -1532,6 +1540,7 @@ impl<'a> Parser<'a> {
|
||||||
{
|
{
|
||||||
self.parse_block_expr(label, lo, BlockCheckMode::Default)
|
self.parse_block_expr(label, lo, BlockCheckMode::Default)
|
||||||
} else if !ate_colon
|
} else if !ate_colon
|
||||||
|
&& self.may_recover()
|
||||||
&& (matches!(self.token.kind, token::CloseDelim(_) | token::Comma)
|
&& (matches!(self.token.kind, token::CloseDelim(_) | token::Comma)
|
||||||
|| self.token.is_op())
|
|| self.token.is_op())
|
||||||
{
|
{
|
||||||
|
@ -1999,6 +2008,10 @@ impl<'a> Parser<'a> {
|
||||||
prev_span: Span,
|
prev_span: Span,
|
||||||
open_delim_span: Span,
|
open_delim_span: Span,
|
||||||
) -> PResult<'a, ()> {
|
) -> PResult<'a, ()> {
|
||||||
|
if !self.may_recover() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
if self.token.kind == token::Comma {
|
if self.token.kind == token::Comma {
|
||||||
if !self.sess.source_map().is_multiline(prev_span.until(self.token.span)) {
|
if !self.sess.source_map().is_multiline(prev_span.until(self.token.span)) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -2039,7 +2052,7 @@ impl<'a> Parser<'a> {
|
||||||
lo: Span,
|
lo: Span,
|
||||||
blk_mode: BlockCheckMode,
|
blk_mode: BlockCheckMode,
|
||||||
) -> PResult<'a, P<Expr>> {
|
) -> PResult<'a, P<Expr>> {
|
||||||
if self.is_array_like_block() {
|
if self.may_recover() && self.is_array_like_block() {
|
||||||
if let Some(arr) = self.maybe_suggest_brackets_instead_of_braces(lo) {
|
if let Some(arr) = self.maybe_suggest_brackets_instead_of_braces(lo) {
|
||||||
return Ok(arr);
|
return Ok(arr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,7 @@ macro_rules! maybe_whole {
|
||||||
macro_rules! maybe_recover_from_interpolated_ty_qpath {
|
macro_rules! maybe_recover_from_interpolated_ty_qpath {
|
||||||
($self: expr, $allow_qpath_recovery: expr) => {
|
($self: expr, $allow_qpath_recovery: expr) => {
|
||||||
if $allow_qpath_recovery
|
if $allow_qpath_recovery
|
||||||
|
&& $self.may_recover()
|
||||||
&& $self.look_ahead(1, |t| t == &token::ModSep)
|
&& $self.look_ahead(1, |t| t == &token::ModSep)
|
||||||
&& let token::Interpolated(nt) = &$self.token.kind
|
&& let token::Interpolated(nt) = &$self.token.kind
|
||||||
&& let token::NtTy(ty) = &**nt
|
&& let token::NtTy(ty) = &**nt
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue