mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
rustc_errors: take self
by value in DiagnosticBuilder::cancel
.
This commit is contained in:
parent
8562d6b752
commit
0b9d70cf6d
@ -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
|
||||
|
@ -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"),
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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"),
|
||||
}
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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!(
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
},
|
||||
|
@ -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);
|
||||
|
@ -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)))
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user