rustc_errors: take self by value in DiagnosticBuilder::cancel.

This commit is contained in:
Eduard-Mihai Burtescu 2022-01-26 03:39:14 +00:00
parent 8562d6b752
commit 0b9d70cf6d
31 changed files with 176 additions and 146 deletions

View File

@ -379,7 +379,7 @@ fn do_mir_borrowck<'a, 'tcx>(
// Convert any reservation warnings into lints.
let reservation_warnings = mem::take(&mut mbcx.reservation_warnings);
for (_, (place, span, location, bk, borrow)) in reservation_warnings {
let mut initial_diag = mbcx.report_conflicting_borrow(location, (place, span), bk, &borrow);
let initial_diag = mbcx.report_conflicting_borrow(location, (place, span), bk, &borrow);
let scope = mbcx.body.source_info(location).scope;
let lint_root = match &mbcx.body.source_scopes[scope].local_data {
@ -2329,7 +2329,7 @@ mod error {
move_out_indices: Vec<MoveOutIndex>,
place_and_err: (PlaceRef<'tcx>, DiagnosticBuilder<'tcx>),
) -> bool {
if let Some((_, mut diag)) =
if let Some((_, diag)) =
self.errors.buffered_move_errors.insert(move_out_indices, place_and_err)
{
// Cancel the old diagnostic so we don't ICE

View File

@ -72,8 +72,8 @@ fn annotation_type_for_level(level: Level) -> AnnotationType {
Level::Warning => AnnotationType::Warning,
Level::Note => AnnotationType::Note,
Level::Help => AnnotationType::Help,
// FIXME(#59346): Not sure how to map these two levels
Level::Cancelled | Level::FailureNote => AnnotationType::Error,
// FIXME(#59346): Not sure how to map this level
Level::FailureNote => AnnotationType::Error,
Level::Allow => panic!("Should not call with Allow"),
}
}

View File

@ -133,7 +133,7 @@ impl Diagnostic {
| Level::Error { .. }
| Level::FailureNote => true,
Level::Warning | Level::Note | Level::Help | Level::Cancelled | Level::Allow => false,
Level::Warning | Level::Note | Level::Help | Level::Allow => false,
}
}
@ -151,17 +151,6 @@ impl Diagnostic {
}
}
/// Cancel the diagnostic (a structured diagnostic must either be emitted or
/// canceled or it will panic when dropped).
pub fn cancel(&mut self) {
self.level = Level::Cancelled;
}
/// Check if this diagnostic [was cancelled][Self::cancel()].
pub fn cancelled(&self) -> bool {
self.level == Level::Cancelled
}
/// Delay emission of this diagnostic as a bug.
///
/// This can be useful in contexts where an error indicates a bug but
@ -174,17 +163,12 @@ impl Diagnostic {
/// locally in whichever way makes the most sense.
#[track_caller]
pub fn downgrade_to_delayed_bug(&mut self) -> &mut Self {
// FIXME(eddyb) this check is only necessary because cancellation exists,
// but hopefully that can be removed in the future, if enough callers
// of `.cancel()` can take `DiagnosticBuilder`, and by-value.
if !self.cancelled() {
assert!(
self.is_error(),
"downgrade_to_delayed_bug: cannot downgrade {:?} to DelayedBug: not an error",
self.level
);
self.level = Level::DelayedBug;
}
assert!(
self.is_error(),
"downgrade_to_delayed_bug: cannot downgrade {:?} to DelayedBug: not an error",
self.level
);
self.level = Level::DelayedBug;
self
}

View File

@ -16,7 +16,7 @@ use tracing::debug;
#[must_use]
#[derive(Clone)]
pub struct DiagnosticBuilder<'a> {
handler: &'a Handler,
state: DiagnosticBuilderState<'a>,
/// `Diagnostic` is a large type, and `DiagnosticBuilder` is often used as a
/// return value, especially within the frequently-used `PResult` type.
@ -25,6 +25,34 @@ pub struct DiagnosticBuilder<'a> {
diagnostic: Box<Diagnostic>,
}
#[derive(Clone)]
enum DiagnosticBuilderState<'a> {
/// Initial state of a `DiagnosticBuilder`, before `.emit()` or `.cancel()`.
///
/// The `Diagnostic` will be emitted through this `Handler`.
Emittable(&'a Handler),
/// State of a `DiagnosticBuilder`, after `.emit()` or *during* `.cancel()`.
///
/// The `Diagnostic` will be ignored when calling `.emit()`, and it can be
/// assumed that `.emit()` was previously called, to end up in this state.
///
/// While this is also used by `.cancel()`, this state is only observed by
/// the `Drop` `impl` of `DiagnosticBuilder`, as `.cancel()` takes `self`
/// by-value specifically to prevent any attempts to `.emit()`.
///
// FIXME(eddyb) currently this doesn't prevent extending the `Diagnostic`,
// despite that being potentially lossy, if important information is added
// *after* the original `.emit()` call.
AlreadyEmittedOrDuringCancellation,
}
// `DiagnosticBuilderState` should be pointer-sized.
rustc_data_structures::static_assert_size!(
DiagnosticBuilderState<'_>,
std::mem::size_of::<&Handler>()
);
/// In general, the `DiagnosticBuilder` uses deref to allow access to
/// the fields and methods of the embedded `diagnostic` in a
/// transparent way. *However,* many of the methods are intended to
@ -78,8 +106,18 @@ impl<'a> DerefMut for DiagnosticBuilder<'a> {
impl<'a> DiagnosticBuilder<'a> {
/// Emit the diagnostic.
pub fn emit(&mut self) {
self.handler.emit_diagnostic(&self);
self.cancel();
match self.state {
// First `.emit()` call, the `&Handler` is still available.
DiagnosticBuilderState::Emittable(handler) => {
handler.emit_diagnostic(&self);
self.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
}
// `.emit()` was previously called, disallowed from repeating it.
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {
// FIXME(eddyb) rely on this to return a "proof" that an error
// was/will be emitted, despite doing no emission *here and now*.
}
}
}
/// Emit the diagnostic unless `delay` is true,
@ -93,6 +131,17 @@ impl<'a> DiagnosticBuilder<'a> {
self.emit();
}
/// Cancel the diagnostic (a structured diagnostic must either be emitted or
/// cancelled or it will panic when dropped).
///
/// This method takes `self` by-value to disallow calling `.emit()` on it,
/// which may be expected to *guarantee* the emission of an error, either
/// at the time of the call, or through a prior `.emit()` call.
pub fn cancel(mut self) {
self.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
drop(self);
}
/// Stashes diagnostic for possible later improvement in a different,
/// later stage of the compiler. The diagnostic can be accessed with
/// the provided `span` and `key` through [`Handler::steal_diagnostic()`].
@ -105,22 +154,29 @@ impl<'a> DiagnosticBuilder<'a> {
}
/// Converts the builder to a `Diagnostic` for later emission,
/// unless handler has disabled such buffering.
/// unless handler has disabled such buffering, or `.emit()` was called.
pub fn into_diagnostic(mut self) -> Option<(Diagnostic, &'a Handler)> {
if self.handler.flags.dont_buffer_diagnostics
|| self.handler.flags.treat_err_as_bug.is_some()
{
let handler = match self.state {
// No `.emit()` calls, the `&Handler` is still available.
DiagnosticBuilderState::Emittable(handler) => handler,
// `.emit()` was previously called, nothing we can do.
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {
return None;
}
};
if handler.flags.dont_buffer_diagnostics || handler.flags.treat_err_as_bug.is_some() {
self.emit();
return None;
}
let handler = self.handler;
// We must use `Level::Cancelled` for `dummy` to avoid an ICE about an
// unused diagnostic.
let dummy = Diagnostic::new(Level::Cancelled, "");
// Take the `Diagnostic` by replacing it with a dummy.
let dummy = Diagnostic::new(Level::Allow, "");
let diagnostic = std::mem::replace(&mut *self.diagnostic, dummy);
// Disable the ICE on `Drop`.
self.cancel();
// Logging here is useful to help track down where in logs an error was
// actually emitted.
debug!("buffer: diagnostic={:?}", diagnostic);
@ -314,7 +370,10 @@ impl<'a> DiagnosticBuilder<'a> {
/// diagnostic.
crate fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> DiagnosticBuilder<'a> {
debug!("Created new diagnostic");
DiagnosticBuilder { handler, diagnostic: Box::new(diagnostic) }
DiagnosticBuilder {
state: DiagnosticBuilderState::Emittable(handler),
diagnostic: Box::new(diagnostic),
}
}
}
@ -324,19 +383,26 @@ impl<'a> Debug for DiagnosticBuilder<'a> {
}
}
/// Destructor bomb - a `DiagnosticBuilder` must be either emitted or canceled
/// Destructor bomb - a `DiagnosticBuilder` must be either emitted or cancelled
/// or we emit a bug.
impl<'a> Drop for DiagnosticBuilder<'a> {
fn drop(&mut self) {
if !panicking() && !self.cancelled() {
let mut db = DiagnosticBuilder::new(
self.handler,
Level::Bug,
"the following error was constructed but not emitted",
);
db.emit();
self.emit();
panic!();
match self.state {
// No `.emit()` or `.cancel()` calls.
DiagnosticBuilderState::Emittable(handler) => {
if !panicking() {
let mut db = DiagnosticBuilder::new(
handler,
Level::Bug,
"the following error was constructed but not emitted",
);
db.emit();
handler.emit_diagnostic(&self);
panic!();
}
}
// `.emit()` was previously called, or maybe we're during `.cancel()`.
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
}
}
}

View File

@ -911,10 +911,6 @@ impl HandlerInner {
// FIXME(eddyb) this should ideally take `diagnostic` by value.
fn emit_diagnostic(&mut self, diagnostic: &Diagnostic) {
if diagnostic.cancelled() {
return;
}
if diagnostic.level == Level::DelayedBug {
// FIXME(eddyb) this should check for `has_errors` and stop pushing
// once *any* errors were emitted (and truncate `delayed_span_bugs`
@ -1238,7 +1234,6 @@ pub enum Level {
Warning,
Note,
Help,
Cancelled,
FailureNote,
Allow,
}
@ -1266,7 +1261,7 @@ impl Level {
spec.set_fg(Some(Color::Cyan)).set_intense(true);
}
FailureNote => {}
Allow | Cancelled => unreachable!(),
Allow => unreachable!(),
}
spec
}
@ -1279,7 +1274,6 @@ impl Level {
Note => "note",
Help => "help",
FailureNote => "failure-note",
Cancelled => panic!("Shouldn't call on cancelled error"),
Allow => panic!("Shouldn't call on allowed error"),
}
}

View File

@ -95,7 +95,7 @@ fn emit_frag_parse_err(
match kind {
// Try a statement if an expression is wanted but failed and suggest adding `;` to call.
AstFragmentKind::Expr => match parse_ast_fragment(orig_parser, AstFragmentKind::Stmts) {
Err(mut err) => err.cancel(),
Err(err) => err.cancel(),
Ok(_) => {
e.note(
"the macro call doesn't expand to an expression, but it can expand to a statement",

View File

@ -1598,7 +1598,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
Some((expected, found)) => Some((expected, found)),
None => {
// Derived error. Cancel the emitter.
diag.cancel();
// NOTE(eddyb) this was `.cancel()`, but `diag`
// is borrowed, so we can't fully defuse it.
diag.downgrade_to_delayed_bug();
return;
}
};

View File

@ -102,7 +102,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
}
match maybe_new_parser_from_source_str(&sess, filename, s.to_string()) {
Ok(mut parser) => match &mut parser.parse_meta_item() {
Ok(mut parser) => match parser.parse_meta_item() {
Ok(meta_item) if parser.token == token::Eof => {
if meta_item.path.segments.len() != 1 {
error!("argument key must be an identifier");
@ -121,7 +121,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
Ok(..) => {}
Err(err) => err.cancel(),
},
Err(errs) => errs.into_iter().for_each(|mut err| err.cancel()),
Err(errs) => drop(errs),
}
// If the user tried to use a key="value" flag, but is missing the quotes, provide
@ -165,7 +165,7 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
}
match maybe_new_parser_from_source_str(&sess, filename, s.to_string()) {
Ok(mut parser) => match &mut parser.parse_meta_item() {
Ok(mut parser) => match parser.parse_meta_item() {
Ok(meta_item) if parser.token == token::Eof => {
if let Some(args) = meta_item.meta_item_list() {
if meta_item.has_name(sym::names) {
@ -210,7 +210,7 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
Ok(..) => {}
Err(err) => err.cancel(),
},
Err(errs) => errs.into_iter().for_each(|mut err| err.cancel()),
Err(errs) => drop(errs),
}
error!(

View File

@ -165,7 +165,7 @@ impl<'a> Parser<'a> {
loop {
// skip any other attributes, we want the item
if snapshot.token.kind == token::Pound {
if let Err(mut err) = snapshot.parse_attribute(InnerAttrPolicy::Permitted) {
if let Err(err) = snapshot.parse_attribute(InnerAttrPolicy::Permitted) {
err.cancel();
return Some(replacement_span);
}
@ -206,7 +206,7 @@ impl<'a> Parser<'a> {
);
return None;
}
Err(mut item_err) => {
Err(item_err) => {
item_err.cancel();
}
Ok(None) => {}
@ -412,12 +412,12 @@ impl<'a> Parser<'a> {
fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
match self.parse_unsuffixed_lit() {
Ok(lit) => return Ok(ast::NestedMetaItem::Literal(lit)),
Err(ref mut err) => err.cancel(),
Err(err) => err.cancel(),
}
match self.parse_meta_item() {
Ok(mi) => return Ok(ast::NestedMetaItem::MetaItem(mi)),
Err(ref mut err) => err.cancel(),
Err(err) => err.cancel(),
}
let found = pprust::token_to_string(&self.token);

View File

@ -461,12 +461,12 @@ impl<'a> Parser<'a> {
tail.could_be_bare_literal = true;
Ok(tail)
}
(Err(mut err), Ok(tail)) => {
(Err(err), Ok(tail)) => {
// We have a block tail that contains a somehow valid type ascription expr.
err.cancel();
Ok(tail)
}
(Err(mut snapshot_err), Err(err)) => {
(Err(snapshot_err), Err(err)) => {
// We don't know what went wrong, emit the normal error.
snapshot_err.cancel();
self.consume_block(token::Brace, ConsumeClosingDelim::Yes);
@ -537,7 +537,7 @@ impl<'a> Parser<'a> {
/// Eats and discards tokens until one of `kets` is encountered. Respects token trees,
/// passes through any errors encountered. Used for error recovery.
pub(super) fn eat_to_tokens(&mut self, kets: &[&TokenKind]) {
if let Err(ref mut err) =
if let Err(err) =
self.parse_seq_to_before_tokens(kets, SeqSep::none(), TokenExpectType::Expect, |p| {
Ok(p.parse_token_tree())
})
@ -703,7 +703,7 @@ impl<'a> Parser<'a> {
*self = snapshot;
}
}
Err(mut err) => {
Err(err) => {
// We couldn't parse generic parameters, unlikely to be a turbofish. Rely on
// generic parse error instead.
err.cancel();
@ -744,14 +744,14 @@ impl<'a> Parser<'a> {
self.mk_expr_err(expr.span.to(self.prev_token.span));
return Ok(());
}
Err(mut err) => {
Err(err) => {
*expr = self.mk_expr_err(expr.span);
err.cancel();
}
}
}
}
Err(mut err) => {
Err(err) => {
err.cancel();
}
_ => {}
@ -821,7 +821,7 @@ impl<'a> Parser<'a> {
enclose(r1.span, r2.span);
true
}
Err(mut expr_err) => {
Err(expr_err) => {
expr_err.cancel();
*self = snapshot;
false
@ -838,7 +838,7 @@ impl<'a> Parser<'a> {
enclose(l1.span, r1.span);
true
}
Err(mut expr_err) => {
Err(expr_err) => {
expr_err.cancel();
*self = snapshot;
false
@ -938,7 +938,7 @@ impl<'a> Parser<'a> {
// `ExprKind::Err` placeholder.
mk_err_expr(self, inner_op.span.to(self.prev_token.span))
}
Err(mut expr_err) => {
Err(expr_err) => {
expr_err.cancel();
// Not entirely sure now, but we bubble the error up with the
// suggestion.
@ -1946,17 +1946,14 @@ impl<'a> Parser<'a> {
Ok(expr)
}
fn recover_const_param_decl(
&mut self,
ty_generics: Option<&Generics>,
) -> PResult<'a, Option<GenericArg>> {
fn recover_const_param_decl(&mut self, ty_generics: Option<&Generics>) -> Option<GenericArg> {
let snapshot = self.clone();
let param = match self.parse_const_param(vec![]) {
Ok(param) => param,
Err(mut err) => {
Err(err) => {
err.cancel();
*self = snapshot;
return Err(err);
return None;
}
};
let mut err =
@ -1977,7 +1974,7 @@ impl<'a> Parser<'a> {
}
let value = self.mk_expr_err(param.span());
err.emit();
return Ok(Some(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value })));
Some(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }))
}
pub fn recover_const_param_declaration(
@ -1985,8 +1982,8 @@ impl<'a> Parser<'a> {
ty_generics: Option<&Generics>,
) -> PResult<'a, Option<GenericArg>> {
// We have to check for a few different cases.
if let Ok(arg) = self.recover_const_param_decl(ty_generics) {
return Ok(arg);
if let Some(arg) = self.recover_const_param_decl(ty_generics) {
return Ok(Some(arg));
}
// We haven't consumed `const` yet.
@ -2085,7 +2082,7 @@ impl<'a> Parser<'a> {
return Ok(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }));
}
}
Err(mut err) => {
Err(err) => {
err.cancel();
}
}
@ -2139,7 +2136,7 @@ impl<'a> Parser<'a> {
Err(mut err) => {
self.bump(); // Skip the `:`.
match self.parse_pat_no_top_alt(expected) {
Err(mut inner_err) => {
Err(inner_err) => {
// Carry on as if we had not done anything, callers will emit a
// reasonable error.
inner_err.cancel();
@ -2246,7 +2243,7 @@ impl<'a> Parser<'a> {
// suggestion-enhanced error here rather than choking on the comma later.
let comma_span = self.token.span;
self.bump();
if let Err(mut err) = self.skip_pat_list() {
if let Err(err) = self.skip_pat_list() {
// We didn't expect this to work anyway; we just wanted to advance to the
// end of the comma-sequence so we know the span to suggest parenthesizing.
err.cancel();

View File

@ -684,7 +684,7 @@ impl<'a> Parser<'a> {
let parser_snapshot_before_type = self.clone();
let cast_expr = match self.parse_as_cast_ty() {
Ok(rhs) => mk_expr(self, lhs, rhs),
Err(mut type_err) => {
Err(type_err) => {
// 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
// `usize < y` as a type with generic arguments.
@ -717,7 +717,7 @@ impl<'a> Parser<'a> {
.emit();
return Ok(expr);
}
Err(mut err) => {
Err(err) => {
err.cancel();
*self = snapshot;
}
@ -773,7 +773,7 @@ impl<'a> Parser<'a> {
expr
}
Err(mut path_err) => {
Err(path_err) => {
// Couldn't parse as a path, return original error and parser state.
path_err.cancel();
*self = parser_snapshot_after_type;
@ -1127,7 +1127,7 @@ impl<'a> Parser<'a> {
snapshot: Option<(Self, ExprKind)>,
) -> Option<P<Expr>> {
match (seq.as_mut(), snapshot) {
(Err(ref mut err), Some((mut snapshot, ExprKind::Path(None, path)))) => {
(Err(err), Some((mut snapshot, ExprKind::Path(None, path)))) => {
let name = pprust::path_to_string(&path);
snapshot.bump(); // `(`
match snapshot.parse_struct_fields(path, false, token::Paren) {
@ -1138,11 +1138,12 @@ impl<'a> Parser<'a> {
let close_paren = self.prev_token.span;
let span = lo.to(self.prev_token.span);
if !fields.is_empty() {
err.cancel();
let mut err = self.struct_span_err(
let replacement_err = self.struct_span_err(
span,
"invalid `struct` delimiters or `fn` call arguments",
);
mem::replace(err, replacement_err).cancel();
err.multipart_suggestion(
&format!("if `{}` is a struct, use braces as delimiters", name),
vec![
@ -1878,7 +1879,7 @@ impl<'a> Parser<'a> {
*self = snapshot;
Some(self.mk_expr_err(arr.span))
}
Err(mut e) => {
Err(e) => {
e.cancel();
None
}
@ -2381,7 +2382,7 @@ impl<'a> Parser<'a> {
return Some(err(self, stmts));
}
}
Err(mut err) => {
Err(err) => {
err.cancel();
}
}
@ -2398,7 +2399,7 @@ impl<'a> Parser<'a> {
}
// We couldn't parse either yet another statement missing it's
// enclosing block nor the next arm's pattern or closing brace.
Err(mut stmt_err) => {
Err(stmt_err) => {
stmt_err.cancel();
*self = start_snapshot;
break;

View File

@ -130,7 +130,7 @@ impl<'a> Parser<'a> {
// FIXME - try to continue parsing other generics?
return Ok((None, TrailingToken::None));
}
Err(mut err) => {
Err(err) => {
err.cancel();
// FIXME - maybe we should overwrite 'self' outside of `collect_tokens`?
*this = snapshot;

View File

@ -1114,7 +1114,7 @@ impl<'a> Parser<'a> {
// Only try to recover if this is implementing a trait for a type
let mut impl_info = match self.parse_item_impl(attrs, defaultness) {
Ok(impl_info) => impl_info,
Err(mut recovery_error) => {
Err(recovery_error) => {
// Recovery failed, raise the "expected identifier" error
recovery_error.cancel();
return Err(err);
@ -1476,7 +1476,9 @@ impl<'a> Parser<'a> {
// after the comma
self.eat(&token::Comma);
// `check_trailing_angle_brackets` already emitted a nicer error
err.cancel();
// NOTE(eddyb) this was `.cancel()`, but `err`
// gets returned, so we can't fully defuse it.
err.downgrade_to_delayed_bug();
}
}
}
@ -2073,7 +2075,7 @@ impl<'a> Parser<'a> {
if let Ok(snippet) = self.span_to_snippet(sp) {
let current_vis = match self.parse_visibility(FollowedByType::No) {
Ok(v) => v,
Err(mut d) => {
Err(d) => {
d.cancel();
return Err(err);
}
@ -2216,7 +2218,7 @@ impl<'a> Parser<'a> {
// If this is a C-variadic argument and we hit an error, return the error.
Err(err) if this.token == token::DotDotDot => return Err(err),
// Recover from attempting to parse the argument as a type without pattern.
Err(mut err) => {
Err(err) => {
err.cancel();
*this = parser_snapshot_before_ty;
this.recover_arg_parse()?
@ -2358,7 +2360,7 @@ impl<'a> Parser<'a> {
match self
.parse_outer_attributes()
.and_then(|_| self.parse_self_param())
.map_err(|mut e| e.cancel())
.map_err(|e| e.cancel())
{
Ok(Some(_)) => "method",
_ => "function",

View File

@ -849,7 +849,7 @@ impl<'a> Parser<'a> {
v.push(t);
continue;
}
Err(mut e) => {
Err(e) => {
// Parsing failed, therefore it must be something more serious
// than just a missing separator.
expect_err.emit();

View File

@ -655,7 +655,7 @@ impl<'a> Parser<'a> {
fn fatal_unexpected_non_pat(
&mut self,
mut err: DiagnosticBuilder<'a>,
err: DiagnosticBuilder<'a>,
expected: Expected,
) -> PResult<'a, P<Pat>> {
err.cancel();
@ -722,7 +722,7 @@ impl<'a> Parser<'a> {
// Ensure the user doesn't receive unhelpful unexpected token errors
self.bump();
if self.is_pat_range_end_start(0) {
let _ = self.parse_pat_range_end().map_err(|mut e| e.cancel());
let _ = self.parse_pat_range_end().map_err(|e| e.cancel());
}
self.error_inclusive_range_with_extra_equals(span_with_eq);

View File

@ -394,7 +394,7 @@ impl<'a> Parser<'a> {
debug!("parse_generic_args_with_leading_angle_bracket_recovery: (snapshotting)");
match self.parse_angle_args(ty_generics) {
Ok(args) => Ok(args),
Err(mut e) if is_first_invocation && self.unmatched_angle_bracket_count > 0 => {
Err(e) if is_first_invocation && self.unmatched_angle_bracket_count > 0 => {
// Swap `self` with our backup of the parser state before attempting to parse
// generic arguments.
let snapshot = mem::replace(self, snapshot.unwrap());

View File

@ -296,7 +296,7 @@ impl<'a> Parser<'a> {
// extra noise.
init
}
(Err(mut init_err), Some((snapshot, _, ty_err))) => {
(Err(init_err), Some((snapshot, _, ty_err))) => {
// init error, ty error
init_err.cancel();
// Couldn't parse the type nor the initializer, only raise the type error and
@ -449,7 +449,7 @@ impl<'a> Parser<'a> {
);
}
}
Err(mut e) => {
Err(e) => {
self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
e.cancel();
}

View File

@ -2001,13 +2001,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// into a single one.
let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node);
parent_err.cancel();
err.message = take(&mut parent_err.message);
err.code = take(&mut parent_err.code);
err.children = take(&mut parent_err.children);
drop(parent_err);
parent_err.cancel();
let def_id = this.parent_scope.module.nearest_parent_mod();

View File

@ -1962,7 +1962,9 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
// Avoid complaining about other inference issues for expressions like
// `42 >> 1`, where the types are still `{integer}`, but we want to
// Do we need `trait_ref.skip_binder().self_ty().is_numeric() &&` too?
err.cancel();
// NOTE(eddyb) this was `.cancel()`, but `err`
// is borrowed, so we can't fully defuse it.
err.downgrade_to_delayed_bug();
return;
}
let post = if post.len() > 4 {

View File

@ -2114,7 +2114,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred);
let ty = parent_trait_ref.skip_binder().self_ty();
if parent_trait_ref.references_error() {
err.cancel();
// NOTE(eddyb) this was `.cancel()`, but `err`
// is borrowed, so we can't fully defuse it.
err.downgrade_to_delayed_bug();
return;
}

View File

@ -69,9 +69,7 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String
match rustc_parse::maybe_new_parser_from_source_str(&sess, file_name, snippet.clone()) {
Ok(parser) => parser,
Err(diagnostics) => {
for mut diagnostic in diagnostics {
diagnostic.cancel();
}
drop(diagnostics);
return None;
}
};
@ -79,7 +77,7 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String
// Reparse a single token tree.
let mut reparsed_trees = match parser.parse_all_token_trees() {
Ok(reparsed_trees) => reparsed_trees,
Err(mut diagnostic) => {
Err(diagnostic) => {
diagnostic.cancel();
return None;
}

View File

@ -551,10 +551,7 @@ crate fn make_test(
let mut parser = match maybe_new_parser_from_source_str(&sess, filename, source) {
Ok(p) => p,
Err(errs) => {
for mut err in errs {
err.cancel();
}
drop(errs);
return (found_main, found_extern_crate, found_macro);
}
};
@ -594,7 +591,7 @@ crate fn make_test(
}
}
Ok(None) => break,
Err(mut e) => {
Err(e) => {
e.cancel();
break;
}

View File

@ -42,7 +42,7 @@ fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> {
let mut p =
new_parser_from_source_str(ps, FileName::Custom(src_as_string.clone()), src_as_string);
p.parse_expr().map_err(|mut e| e.cancel()).ok()
p.parse_expr().map_err(|e| e.cancel()).ok()
}
// Helper functions for building exprs

View File

@ -628,9 +628,7 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code) {
Ok(p) => p,
Err(errs) => {
for mut err in errs {
err.cancel();
}
drop(errs);
return false;
},
};
@ -668,7 +666,7 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
_ => {},
},
Ok(None) => break,
Err(mut e) => {
Err(e) => {
e.cancel();
return false;
},

View File

@ -534,7 +534,7 @@ impl Write {
match parser
.parse_expr()
.map(rustc_ast::ptr::P::into_inner)
.map_err(|mut e| e.cancel())
.map_err(|e| e.cancel())
{
// write!(e, ...)
Ok(p) if parser.eat(&token::Comma) => Some(p),
@ -563,7 +563,7 @@ impl Write {
}
let comma_span = parser.prev_token.span;
let token_expr = if let Ok(expr) = parser.parse_expr().map_err(|mut err| err.cancel()) {
let token_expr = if let Ok(expr) = parser.parse_expr().map_err(|err| err.cancel()) {
expr
} else {
return (Some(fmtstr), None);

View File

@ -439,7 +439,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
}
}
Err(mod_err) if !mods_outside_ast.is_empty() => {
if let ModError::ParserError(mut e) = mod_err {
if let ModError::ParserError(e) = mod_err {
e.cancel();
}
Ok(Some(SubModKind::MultiExternal(mods_outside_ast)))

View File

@ -57,7 +57,7 @@ fn parse_cfg_if_inner<'a>(
let item = match parser.parse_item(ForceCollect::No) {
Ok(Some(item_ptr)) => item_ptr.into_inner(),
Ok(None) => continue,
Err(mut err) => {
Err(err) => {
err.cancel();
parser.sess.span_diagnostic.reset_err_count();
return Err(

View File

@ -23,7 +23,7 @@ pub(crate) fn parse_lazy_static(
val
}
}
Err(mut err) => {
Err(err) => {
err.cancel();
parser.sess.span_diagnostic.reset_err_count();
return None;

View File

@ -36,7 +36,7 @@ fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option<MacroArg> {
return Some(MacroArg::$macro_arg($f(x)?));
}
}
Err(mut e) => {
Err(e) => {
e.cancel();
parser.sess.span_diagnostic.reset_err_count();
}

View File

@ -115,7 +115,7 @@ impl<'a> Parser<'a> {
match parser.parse_mod(&TokenKind::Eof) {
Ok(result) => Some(result),
Err(mut e) => {
sess.emit_or_cancel_diagnostic(&mut e);
e.emit();
if sess.can_reset_errors() {
sess.reset_errors();
}

View File

@ -230,17 +230,6 @@ impl ParseSess {
}
}
pub(crate) fn emit_or_cancel_diagnostic(&self, diagnostic: &mut Diagnostic) {
self.parse_sess.span_diagnostic.emit_diagnostic(diagnostic);
// The Handler will check whether the diagnostic should be emitted
// based on the user's rustfmt configuration and the originating file
// that caused the parser error. If the Handler determined it should skip
// emission then we need to ensure the diagnostic is cancelled.
if !diagnostic.cancelled() {
diagnostic.cancel();
}
}
pub(super) fn can_reset_errors(&self) -> bool {
self.can_reset_errors.load(Ordering::Acquire)
}