Remove a second DiagnosticBuilder::emit_without_consuming
call.
Instead of taking `seq` as a mutable reference, `maybe_recover_struct_lit_bad_delims` now consumes `seq` on the recovery path, and returns `seq` unchanged on the non-recovery path. The commit also combines an `if` and a `match` to merge two identical paths. Also change `recover_seq_parse_error` so it receives a `PErr` instead of a `PResult`, because all the call sites now handle the `Ok`/`Err` distinction themselves.
This commit is contained in:
parent
1881055000
commit
3ce34f42e1
2 changed files with 30 additions and 39 deletions
|
@ -35,7 +35,7 @@ use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
pluralize, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, FatalError,
|
pluralize, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, FatalError,
|
||||||
PResult,
|
PErr, PResult,
|
||||||
};
|
};
|
||||||
use rustc_session::errors::ExprParenthesesNeeded;
|
use rustc_session::errors::ExprParenthesesNeeded;
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
|
@ -2044,17 +2044,12 @@ impl<'a> Parser<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
delim: Delimiter,
|
delim: Delimiter,
|
||||||
lo: Span,
|
lo: Span,
|
||||||
result: PResult<'a, P<Expr>>,
|
err: PErr<'a>,
|
||||||
) -> P<Expr> {
|
) -> P<Expr> {
|
||||||
match result {
|
err.emit();
|
||||||
Ok(x) => x,
|
// Recover from parse error, callers expect the closing delim to be consumed.
|
||||||
Err(err) => {
|
self.consume_block(delim, ConsumeClosingDelim::Yes);
|
||||||
err.emit();
|
self.mk_expr(lo.to(self.prev_token.span), ExprKind::Err)
|
||||||
// Recover from parse error, callers expect the closing delim to be consumed.
|
|
||||||
self.consume_block(delim, ConsumeClosingDelim::Yes);
|
|
||||||
self.mk_expr(lo.to(self.prev_token.span), ExprKind::Err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Eats tokens until we can be relatively sure we reached the end of the
|
/// Eats tokens until we can be relatively sure we reached the end of the
|
||||||
|
|
|
@ -1272,15 +1272,13 @@ impl<'a> Parser<'a> {
|
||||||
};
|
};
|
||||||
let open_paren = self.token.span;
|
let open_paren = self.token.span;
|
||||||
|
|
||||||
let mut seq = self
|
let seq = self
|
||||||
.parse_expr_paren_seq()
|
.parse_expr_paren_seq()
|
||||||
.map(|args| self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args)));
|
.map(|args| self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args)));
|
||||||
if let Some(expr) =
|
match self.maybe_recover_struct_lit_bad_delims(lo, open_paren, seq, snapshot) {
|
||||||
self.maybe_recover_struct_lit_bad_delims(lo, open_paren, &mut seq, snapshot)
|
Ok(expr) => expr,
|
||||||
{
|
Err(err) => self.recover_seq_parse_error(Delimiter::Parenthesis, lo, err),
|
||||||
return expr;
|
|
||||||
}
|
}
|
||||||
self.recover_seq_parse_error(Delimiter::Parenthesis, lo, seq)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If we encounter a parser state that looks like the user has written a `struct` literal with
|
/// If we encounter a parser state that looks like the user has written a `struct` literal with
|
||||||
|
@ -1290,14 +1288,11 @@ impl<'a> Parser<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
lo: Span,
|
lo: Span,
|
||||||
open_paren: Span,
|
open_paren: Span,
|
||||||
seq: &mut PResult<'a, P<Expr>>,
|
seq: PResult<'a, P<Expr>>,
|
||||||
snapshot: Option<(SnapshotParser<'a>, ExprKind)>,
|
snapshot: Option<(SnapshotParser<'a>, ExprKind)>,
|
||||||
) -> Option<P<Expr>> {
|
) -> PResult<'a, P<Expr>> {
|
||||||
if !self.may_recover() {
|
match (self.may_recover(), seq, snapshot) {
|
||||||
return None;
|
(true, Err(err), Some((mut snapshot, ExprKind::Path(None, path)))) => {
|
||||||
}
|
|
||||||
match (seq.as_mut(), snapshot) {
|
|
||||||
(Err(err), Some((mut snapshot, ExprKind::Path(None, path)))) => {
|
|
||||||
snapshot.bump(); // `(`
|
snapshot.bump(); // `(`
|
||||||
match snapshot.parse_struct_fields(path.clone(), false, Delimiter::Parenthesis) {
|
match snapshot.parse_struct_fields(path.clone(), false, Delimiter::Parenthesis) {
|
||||||
Ok((fields, ..))
|
Ok((fields, ..))
|
||||||
|
@ -1315,11 +1310,13 @@ impl<'a> Parser<'a> {
|
||||||
if !fields.is_empty() &&
|
if !fields.is_empty() &&
|
||||||
// `token.kind` should not be compared here.
|
// `token.kind` should not be compared here.
|
||||||
// This is because the `snapshot.token.kind` is treated as the same as
|
// This is because the `snapshot.token.kind` is treated as the same as
|
||||||
// that of the open delim in `TokenTreesReader::parse_token_tree`, even if they are different.
|
// that of the open delim in `TokenTreesReader::parse_token_tree`, even
|
||||||
|
// if they are different.
|
||||||
self.span_to_snippet(close_paren).is_ok_and(|snippet| snippet == ")")
|
self.span_to_snippet(close_paren).is_ok_and(|snippet| snippet == ")")
|
||||||
{
|
{
|
||||||
let mut replacement_err =
|
err.cancel();
|
||||||
self.dcx().create_err(errors::ParenthesesWithStructFields {
|
self.dcx()
|
||||||
|
.create_err(errors::ParenthesesWithStructFields {
|
||||||
span,
|
span,
|
||||||
r#type: path,
|
r#type: path,
|
||||||
braces_for_struct: errors::BracesForStructLiteral {
|
braces_for_struct: errors::BracesForStructLiteral {
|
||||||
|
@ -1332,23 +1329,22 @@ impl<'a> Parser<'a> {
|
||||||
.map(|field| field.span.until(field.expr.span))
|
.map(|field| field.span.until(field.expr.span))
|
||||||
.collect(),
|
.collect(),
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
replacement_err.emit_without_consuming();
|
.emit();
|
||||||
|
|
||||||
let old_err = mem::replace(err, replacement_err);
|
|
||||||
old_err.cancel();
|
|
||||||
} else {
|
} else {
|
||||||
err.emit_without_consuming();
|
err.emit();
|
||||||
}
|
}
|
||||||
return Some(self.mk_expr_err(span));
|
Ok(self.mk_expr_err(span))
|
||||||
|
}
|
||||||
|
Ok(_) => Err(err),
|
||||||
|
Err(err2) => {
|
||||||
|
err2.cancel();
|
||||||
|
Err(err)
|
||||||
}
|
}
|
||||||
Ok(_) => {}
|
|
||||||
Err(err) => err.cancel(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
(_, seq, _) => seq,
|
||||||
}
|
}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse an indexing expression `expr[...]`.
|
/// Parse an indexing expression `expr[...]`.
|
||||||
|
@ -1552,7 +1548,7 @@ impl<'a> Parser<'a> {
|
||||||
) {
|
) {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Ok(self.recover_seq_parse_error(Delimiter::Parenthesis, lo, Err(err)));
|
return Ok(self.recover_seq_parse_error(Delimiter::Parenthesis, lo, err));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let kind = if es.len() == 1 && !trailing_comma {
|
let kind = if es.len() == 1 && !trailing_comma {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue