From bb8d4307eb723850e98bcb52d71d860a4aba220a Mon Sep 17 00:00:00 2001 From: mark Date: Sat, 22 Jan 2022 18:49:12 -0600 Subject: [PATCH] rustc_error: make ErrorReported impossible to construct There are a few places were we have to construct it, though, and a few places that are more invasive to change. To do this, we create a constructor with a long obvious name. --- compiler/rustc_ast_lowering/src/lib.rs | 2 +- .../rustc_ast_passes/src/ast_validation.rs | 2 +- compiler/rustc_ast_passes/src/feature_gate.rs | 11 +- compiler/rustc_borrowck/src/lib.rs | 8 +- .../rustc_codegen_cranelift/src/constant.rs | 3 +- compiler/rustc_codegen_ssa/src/mir/mod.rs | 3 +- .../src/const_eval/machine.rs | 5 +- .../rustc_const_eval/src/interpret/intern.rs | 7 +- .../rustc_const_eval/src/interpret/operand.rs | 7 +- .../src/transform/check_consts/check.rs | 6 +- compiler/rustc_driver/src/lib.rs | 8 +- .../rustc_errors/src/diagnostic_builder.rs | 6 +- compiler/rustc_errors/src/lib.rs | 95 ++++++++++------ compiler/rustc_expand/src/base.rs | 2 +- compiler/rustc_expand/src/mbe/macro_rules.rs | 8 +- compiler/rustc_expand/src/proc_macro.rs | 6 +- compiler/rustc_incremental/src/persist/fs.rs | 11 +- .../nice_region_error/different_lifetimes.rs | 4 +- .../mismatched_static_lifetime.rs | 4 +- .../error_reporting/nice_region_error/mod.rs | 5 +- .../nice_region_error/static_impl_trait.rs | 8 +- .../trait_impl_difference.rs | 22 ++-- .../src/infer/outlives/obligations.rs | 2 +- compiler/rustc_interface/src/passes.rs | 26 +++-- compiler/rustc_interface/src/queries.rs | 7 +- compiler/rustc_lint/src/builtin.rs | 36 +++--- compiler/rustc_lint/src/context.rs | 16 ++- compiler/rustc_lint/src/early.rs | 4 +- compiler/rustc_lint/src/levels.rs | 2 +- compiler/rustc_lint/src/non_ascii_idents.rs | 6 +- compiler/rustc_lint/src/noop_method_call.rs | 2 +- compiler/rustc_lint/src/traits.rs | 4 +- compiler/rustc_lint/src/types.rs | 6 +- compiler/rustc_lint/src/unused.rs | 10 +- compiler/rustc_metadata/src/creader.rs | 8 +- compiler/rustc_metadata/src/native_libs.rs | 50 +++++---- compiler/rustc_middle/src/lint.rs | 26 +++-- compiler/rustc_middle/src/middle/stability.rs | 4 +- .../rustc_middle/src/mir/interpret/error.rs | 4 +- compiler/rustc_middle/src/query/mod.rs | 4 +- .../src/traits/specialization_graph.rs | 10 +- compiler/rustc_middle/src/ty/adt.rs | 3 +- compiler/rustc_middle/src/ty/consts.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 20 ++-- compiler/rustc_middle/src/ty/fold.rs | 8 ++ compiler/rustc_mir_build/src/build/mod.rs | 8 +- .../rustc_mir_build/src/check_unsafety.rs | 9 +- compiler/rustc_mir_build/src/thir/cx/mod.rs | 14 ++- .../src/thir/pattern/const_to_pat.rs | 32 ++++-- .../src/check_const_item_mutation.rs | 4 +- .../src/check_packed_ref.rs | 4 +- .../rustc_mir_transform/src/const_prop.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 10 +- .../src/lexer/unescape_error_reporting.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 6 +- compiler/rustc_passes/src/check_attr.rs | 4 +- compiler/rustc_passes/src/liveness.rs | 4 +- compiler/rustc_passes/src/stability.rs | 6 +- compiler/rustc_privacy/src/lib.rs | 6 +- .../rustc_resolve/src/late/diagnostics.rs | 2 +- compiler/rustc_resolve/src/late/lifetimes.rs | 12 +- compiler/rustc_session/src/output.rs | 2 +- compiler/rustc_session/src/session.rs | 45 +++++--- .../src/traits/codegen.rs | 8 +- .../src/traits/const_evaluatable.rs | 27 +++-- .../src/traits/error_reporting/mod.rs | 18 +-- .../src/traits/fulfill.rs | 15 +-- .../rustc_trait_selection/src/traits/mod.rs | 14 ++- .../src/traits/on_unimplemented.rs | 38 +++---- .../src/traits/project.rs | 2 +- .../src/traits/select/mod.rs | 6 +- .../src/traits/specialize/mod.rs | 41 ++++--- compiler/rustc_ty_utils/src/instance.rs | 4 +- compiler/rustc_typeck/src/astconv/errors.rs | 7 +- compiler/rustc_typeck/src/astconv/generics.rs | 104 +++++++++--------- compiler/rustc_typeck/src/astconv/mod.rs | 37 ++++--- compiler/rustc_typeck/src/check/cast.rs | 25 +++-- compiler/rustc_typeck/src/check/check.rs | 36 +++--- .../rustc_typeck/src/check/compare_method.rs | 70 ++++++------ compiler/rustc_typeck/src/check/dropck.rs | 16 +-- compiler/rustc_typeck/src/check/expr.rs | 4 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 24 ++-- .../rustc_typeck/src/check/method/probe.rs | 4 +- compiler/rustc_typeck/src/check/writeback.rs | 10 +- compiler/rustc_typeck/src/coherence/orphan.rs | 12 +- compiler/rustc_typeck/src/collect/type_of.rs | 4 +- compiler/rustc_typeck/src/expr_use_visitor.rs | 2 +- compiler/rustc_typeck/src/lib.rs | 2 +- src/librustdoc/clean/types.rs | 4 +- src/librustdoc/core.rs | 2 +- src/librustdoc/doctest.rs | 2 +- src/librustdoc/lib.rs | 16 ++- src/librustdoc/passes/bare_urls.rs | 2 +- .../passes/check_code_block_syntax.rs | 2 +- .../passes/check_doc_test_visibility.rs | 8 +- .../auxiliary/issue-40001-plugin.rs | 2 +- .../auxiliary/lint-for-crate-rpass.rs | 2 +- .../ui-fulldeps/auxiliary/lint-for-crate.rs | 2 +- .../auxiliary/lint-group-plugin-test.rs | 4 +- .../ui-fulldeps/auxiliary/lint-plugin-test.rs | 2 +- .../ui-fulldeps/auxiliary/lint-tool-test.rs | 4 +- .../rustfmt/src/parse/macros/lazy_static.rs | 2 +- src/tools/rustfmt/src/parse/macros/mod.rs | 2 +- src/tools/rustfmt/src/parse/session.rs | 2 +- 104 files changed, 704 insertions(+), 549 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c1680be9c0ad5..abf1bc739a3f7 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -952,7 +952,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { sess.diagnostic().delay_span_bug( span, "unexpected delimiter in key-value attribute's value", - ) + ); } unwrap_single_token(sess, tokens, span) } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 8f0b12cb4feef..f5e6b15fcbfd1 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -440,7 +440,7 @@ impl<'a> AstValidator<'a> { attr.span, "allow, cfg, cfg_attr, deny, \ forbid, and warn are the only allowed built-in attributes in function parameters", - ) + ); } }); } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 097bd07c74ce8..5b6147c72230d 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -252,11 +252,12 @@ impl<'a> PostExpansionVisitor<'a> { "wasm ABI is experimental and subject to change" ); } - abi => self - .sess - .parse_sess - .span_diagnostic - .delay_span_bug(span, &format!("unrecognized ABI not caught in lowering: {}", abi)), + abi => { + self.sess.parse_sess.span_diagnostic.delay_span_bug( + span, + &format!("unrecognized ABI not caught in lowering: {}", abi), + ); + } } } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 7502a3e39a191..c9c973bd34350 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -178,7 +178,7 @@ fn do_mir_borrowck<'a, 'tcx>( // Gather the upvars of a closure, if any. let tables = tcx.typeck_opt_const_arg(def); - if let Some(ErrorGuaranteed) = tables.tainted_by_errors { + if let Some(ErrorGuaranteed { .. }) = tables.tainted_by_errors { infcx.set_tainted_by_errors(); errors.set_tainted_by_errors(); } @@ -2274,6 +2274,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } mod error { + use rustc_errors::ErrorGuaranteed; + use super::*; pub struct BorrowckErrors<'tcx> { @@ -2311,7 +2313,7 @@ mod error { // FIXME(eddyb) this is a suboptimal API because `tainted_by_errors` is // set before any emission actually happens (weakening the guarantee). pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) { - self.tainted_by_errors = Some(ErrorGuaranteed {}); + self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); t.buffer(&mut self.buffered); } @@ -2320,7 +2322,7 @@ mod error { } pub fn set_tainted_by_errors(&mut self) { - self.tainted_by_errors = Some(ErrorGuaranteed {}); + self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); } } diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index aff3603303a98..4657791345b8e 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -1,7 +1,6 @@ //! Handling of `static`s, `const`s and promoted allocations use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::ErrorGuaranteed; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{ read_target_uint, AllocId, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar, @@ -54,7 +53,7 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { { all_constants_ok = false; match err { - ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted => { + ErrorHandled::Reported(_) | ErrorHandled::Linted => { fx.tcx.sess.span_err(constant.span, "erroneous constant encountered"); } ErrorHandled::TooGeneric => { diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 40a8e2388e26b..6c139df0a8555 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -1,5 +1,4 @@ use crate::traits::*; -use rustc_errors::ErrorGuaranteed; use rustc_middle::mir; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout}; @@ -191,7 +190,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( all_consts_ok = false; match err { // errored or at least linted - ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted => {} + ErrorHandled::Reported(_) | ErrorHandled::Linted => {} ErrorHandled::TooGeneric => { span_bug!(const_.span, "codgen encountered polymorphic constant: {:?}", err) } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 92f4d3a677244..2b58c1e8233c1 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -1,4 +1,3 @@ -use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_middle::mir; use rustc_middle::ty::{self, Ty}; @@ -247,11 +246,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, if ecx.tcx.is_ctfe_mir_available(def.did) { Ok(ecx.tcx.mir_for_ctfe_opt_const_arg(def)) } else if ecx.tcx.def_kind(def.did) == DefKind::AssocConst { - ecx.tcx.sess.delay_span_bug( + let guar = ecx.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, "This is likely a const item that is missing from its impl", ); - throw_inval!(AlreadyReported(ErrorGuaranteed {})); + throw_inval!(AlreadyReported(guar)); } else { let path = ecx.tcx.def_path_str(def.did); Err(ConstEvalErrKind::NeedsRfc(format!("calling extern function `{}`", path)) diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 9f507bface221..43ab74f4b888a 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -406,8 +406,11 @@ pub fn intern_const_alloc_recursive< } else if ecx.memory.dead_alloc_map.contains_key(&alloc_id) { // Codegen does not like dangling pointers, and generally `tcx` assumes that // all allocations referenced anywhere actually exist. So, make sure we error here. - ecx.tcx.sess.span_err(ecx.tcx.span, "encountered dangling pointer in final constant"); - return Err(ErrorGuaranteed); + let reported = ecx + .tcx + .sess + .span_err(ecx.tcx.span, "encountered dangling pointer in final constant"); + return Err(reported); } else if ecx.tcx.get_global_alloc(alloc_id).is_none() { // We have hit an `AllocId` that is neither in local or global memory and isn't // marked as dangling by local memory. That should be impossible. diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 2fae53bb9bdf5..9000567558b84 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -4,12 +4,11 @@ use std::convert::TryFrom; use std::fmt::Write; -use rustc_errors::ErrorGuaranteed; use rustc_hir::def::Namespace; use rustc_macros::HashStable; use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer}; -use rustc_middle::ty::{ConstInt, Ty}; +use rustc_middle::ty::{ConstInt, DelaySpanBugEmitted, Ty}; use rustc_middle::{mir, ty}; use rustc_target::abi::{Abi, HasDataLayout, Size, TagEncoding}; use rustc_target::abi::{VariantIdx, Variants}; @@ -565,7 +564,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { match val.val() { ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric), - ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorGuaranteed)), + ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => { + throw_inval!(AlreadyReported(reported)) + } ty::ConstKind::Unevaluated(uv) => { let instance = self.resolve(uv.def, uv.substs)?; Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into()) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 7dc279cc840fb..eb01e261c1a55 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -259,7 +259,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { self.tcx.sess.diagnostic().emit_diagnostic(&error); } } else { - assert!(self.tcx.sess.has_errors()); + assert!(self.tcx.sess.has_errors().is_some()); } } @@ -327,8 +327,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { match op.importance() { ops::DiagnosticImportance::Primary => { - self.error_emitted = Some(ErrorGuaranteed); - err.emit(); + let reported = err.emit(); + self.error_emitted = Some(reported); } ops::DiagnosticImportance::Secondary => err.buffer(&mut self.secondary_errors), diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 43c9e9296b90a..91bb38e5a95d5 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -235,7 +235,7 @@ fn run_compiler( }; match make_input(config.opts.error_format, &matches.free) { - Err(ErrorGuaranteed) => return Err(ErrorGuaranteed), + Err(reported) => return Err(reported), Ok(Some((input, input_file_path))) => { config.input = input; config.input_path = input_file_path; @@ -465,11 +465,11 @@ fn make_input( if io::stdin().read_to_string(&mut src).is_err() { // Immediately stop compilation if there was an issue reading // the input (for example if the input stream is not UTF-8). - early_error_no_abort( + let reported = early_error_no_abort( error_format, "couldn't read from stdin, as it did not contain valid UTF-8", ); - return Err(ErrorGuaranteed); + return Err(reported); } if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") { let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect( @@ -1128,7 +1128,7 @@ fn extra_compiler_flags() -> Option<(Vec, bool)> { pub fn catch_fatal_errors R, R>(f: F) -> Result { catch_unwind(panic::AssertUnwindSafe(f)).map_err(|value| { if value.is::() { - ErrorGuaranteed + ErrorGuaranteed::unchecked_claim_error_was_emitted() } else { panic::resume_unwind(value); } diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 98b8b2a569edd..72471638a966b 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -128,7 +128,7 @@ impl EmissionGuarantee for ErrorGuaranteed { DiagnosticBuilderState::Emittable(handler) => { db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; - handler.emit_diagnostic(&db.inner.diagnostic); + let guar = handler.emit_diagnostic(&db.inner.diagnostic); // Only allow a guarantee if the `level` wasn't switched to a // non-error - the field isn't `pub`, but the whole `Diagnostic` @@ -139,7 +139,7 @@ impl EmissionGuarantee for ErrorGuaranteed { from `DiagnosticBuilder`", db.inner.diagnostic.level, ); - ErrorGuaranteed + guar.unwrap() } // `.emit()` was previously called, disallowed from repeating it, // but can take advantage of the previous `.emit()`'s guarantee @@ -154,7 +154,7 @@ impl EmissionGuarantee for ErrorGuaranteed { became non-error ({:?}), after original `.emit()`", db.inner.diagnostic.level, ); - ErrorGuaranteed + ErrorGuaranteed::unchecked_claim_error_was_emitted() } } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 345247b07001b..c719e4910ce4e 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -399,7 +399,7 @@ impl fmt::Display for ExplicitBug { impl error::Error for ExplicitBug {} pub use diagnostic::{Diagnostic, DiagnosticId, DiagnosticStyledString, SubDiagnostic}; -pub use diagnostic_builder::DiagnosticBuilder; +pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee}; use std::backtrace::Backtrace; /// A handler deals with errors and other compiler output. @@ -644,8 +644,8 @@ impl Handler { } /// Emit all stashed diagnostics. - pub fn emit_stashed_diagnostics(&self) { - self.inner.borrow_mut().emit_stashed_diagnostics(); + pub fn emit_stashed_diagnostics(&self) -> Option { + self.inner.borrow_mut().emit_stashed_diagnostics() } /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. @@ -805,8 +805,8 @@ impl Handler { FatalError.raise() } - pub fn span_err(&self, span: impl Into, msg: &str) { - self.emit_diag_at_span(Diagnostic::new(Error { lint: false }, msg), span); + pub fn span_err(&self, span: impl Into, msg: &str) -> ErrorGuaranteed { + self.emit_diag_at_span(Diagnostic::new(Error { lint: false }, msg), span).unwrap() } pub fn span_err_with_code(&self, span: impl Into, msg: &str, code: DiagnosticId) { @@ -829,7 +829,7 @@ impl Handler { } #[track_caller] - pub fn delay_span_bug(&self, span: impl Into, msg: &str) { + pub fn delay_span_bug(&self, span: impl Into, msg: &str) -> ErrorGuaranteed { self.inner.borrow_mut().delay_span_bug(span, msg) } @@ -858,8 +858,8 @@ impl Handler { self.inner.borrow_mut().fatal(msg) } - pub fn err(&self, msg: &str) { - self.inner.borrow_mut().err(msg); + pub fn err(&self, msg: &str) -> ErrorGuaranteed { + self.inner.borrow_mut().err(msg) } pub fn warn(&self, msg: &str) { @@ -880,11 +880,15 @@ impl Handler { self.inner.borrow().err_count() } - pub fn has_errors(&self) -> bool { - self.inner.borrow().has_errors() + pub fn has_errors(&self) -> Option { + if self.inner.borrow().has_errors() { Some(ErrorGuaranteed(())) } else { None } } - pub fn has_errors_or_lint_errors(&self) -> bool { - self.inner.borrow().has_errors_or_lint_errors() + pub fn has_errors_or_lint_errors(&self) -> Option { + if self.inner.borrow().has_errors_or_lint_errors() { + Some(ErrorGuaranteed(())) + } else { + None + } } pub fn has_errors_or_delayed_span_bugs(&self) -> bool { self.inner.borrow().has_errors_or_delayed_span_bugs() @@ -915,13 +919,17 @@ impl Handler { self.inner.borrow_mut().force_print_diagnostic(db) } - pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) { + pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) -> Option { self.inner.borrow_mut().emit_diagnostic(diagnostic) } - fn emit_diag_at_span(&self, mut diag: Diagnostic, sp: impl Into) { + fn emit_diag_at_span( + &self, + mut diag: Diagnostic, + sp: impl Into, + ) -> Option { let mut inner = self.inner.borrow_mut(); - inner.emit_diagnostic(diag.set_span(sp)); + inner.emit_diagnostic(diag.set_span(sp)) } pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { @@ -990,13 +998,20 @@ impl HandlerInner { } /// Emit all stashed diagnostics. - fn emit_stashed_diagnostics(&mut self) { + fn emit_stashed_diagnostics(&mut self) -> Option { let diags = self.stashed_diagnostics.drain(..).map(|x| x.1).collect::>(); - diags.iter().for_each(|diag| self.emit_diagnostic(diag)); + let mut reported = None; + diags.iter().for_each(|diag| { + if diag.is_error() { + reported = Some(ErrorGuaranteed(())); + } + self.emit_diagnostic(diag); + }); + reported } // FIXME(eddyb) this should ideally take `diagnostic` by value. - fn emit_diagnostic(&mut self, diagnostic: &Diagnostic) { + fn emit_diagnostic(&mut self, diagnostic: &Diagnostic) -> Option { 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` @@ -1005,7 +1020,7 @@ impl HandlerInner { self.delayed_span_bugs.push(diagnostic.clone()); if !self.flags.report_delayed_bugs { - return; + return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); } } @@ -1020,7 +1035,7 @@ impl HandlerInner { if diagnostic.has_future_breakage() { (*TRACK_DIAGNOSTICS)(diagnostic); } - return; + return None; } // The `LintExpectationId` can be stable or unstable depending on when it was created. @@ -1029,16 +1044,16 @@ impl HandlerInner { // a stable one by the `LintLevelsBuilder`. if let Level::Expect(LintExpectationId::Unstable { .. }) = diagnostic.level { self.unstable_expect_diagnostics.push(diagnostic.clone()); - return; + return None; } (*TRACK_DIAGNOSTICS)(diagnostic); if let Level::Expect(expectation_id) = diagnostic.level { self.fulfilled_expectations.insert(expectation_id); - return; + return None; } else if diagnostic.level == Allow { - return; + return None; } if let Some(ref code) = diagnostic.code { @@ -1068,8 +1083,12 @@ impl HandlerInner { } else { self.bump_err_count(); } + + Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) } else { self.bump_warn_count(); + + None } } @@ -1191,7 +1210,7 @@ impl HandlerInner { } #[track_caller] - fn delay_span_bug(&mut self, sp: impl Into, msg: &str) { + fn delay_span_bug(&mut self, sp: impl Into, msg: &str) -> ErrorGuaranteed { // This is technically `self.treat_err_as_bug()` but `delay_span_bug` is called before // incrementing `err_count` by one, so we need to +1 the comparing. // FIXME: Would be nice to increment err_count in a more coherent way. @@ -1202,7 +1221,7 @@ impl HandlerInner { let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg); diagnostic.set_span(sp.into()); diagnostic.note(&format!("delayed at {}", std::panic::Location::caller())); - self.emit_diagnostic(&diagnostic) + self.emit_diagnostic(&diagnostic).unwrap() } // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's @@ -1221,20 +1240,20 @@ impl HandlerInner { } fn fatal(&mut self, msg: &str) -> FatalError { - self.emit_error(Fatal, msg); + self.emit(Fatal, msg); FatalError } - fn err(&mut self, msg: &str) { - self.emit_error(Error { lint: false }, msg); + fn err(&mut self, msg: &str) -> ErrorGuaranteed { + self.emit(Error { lint: false }, msg) } /// Emit an error; level should be `Error` or `Fatal`. - fn emit_error(&mut self, level: Level, msg: &str) { + fn emit(&mut self, level: Level, msg: &str) -> ErrorGuaranteed { if self.treat_err_as_bug() { self.bug(msg); } - self.emit_diagnostic(&Diagnostic::new(level, msg)); + self.emit_diagnostic(&Diagnostic::new(level, msg)).unwrap() } fn bug(&mut self, msg: &str) -> ! { @@ -1433,9 +1452,17 @@ pub fn add_elided_lifetime_in_path_suggestion( ); } -// Useful type to use with `Result<>` indicate that an error has already -// been reported to the user, so no need to continue checking. -#[derive(Clone, Copy, Debug, Encodable, Decodable, Hash, PartialEq, Eq)] -pub struct ErrorGuaranteed; +/// Useful type to use with `Result<>` indicate that an error has already +/// been reported to the user, so no need to continue checking. +#[derive(Clone, Copy, Debug, Encodable, Decodable, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct ErrorGuaranteed(()); + +impl ErrorGuaranteed { + /// To be used only if you really know what you are doing... ideally, we would find a way to + /// eliminate all calls to this method. + pub fn unchecked_claim_error_was_emitted() -> Self { + ErrorGuaranteed(()) + } +} rustc_data_structures::impl_stable_hash_via_hash!(ErrorGuaranteed); diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 1263f31f6aa1b..d6b308cdf85d5 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1330,7 +1330,7 @@ pub fn parse_macro_name_and_helper_attrs( let attributes_attr = list.get(1); let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr { if !attr.has_name(sym::attributes) { - diag.span_err(attr.span(), "second argument must be `attributes`") + diag.span_err(attr.span(), "second argument must be `attributes`"); } attr.meta_item_list() .unwrap_or_else(|| { diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index c3b1b34aa29b9..b93edf8da7a64 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -534,10 +534,10 @@ pub fn compile_declarative_macro( let (transparency, transparency_error) = attr::find_transparency(&def.attrs, macro_rules); match transparency_error { Some(TransparencyError::UnknownTransparency(value, span)) => { - diag.span_err(span, &format!("unknown macro transparency: `{}`", value)) + diag.span_err(span, &format!("unknown macro transparency: `{}`", value)); } Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) => { - diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes") + diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes"); } None => {} } @@ -617,7 +617,9 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool { fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool { match *rhs { mbe::TokenTree::Delimited(..) => return true, - _ => sess.span_diagnostic.span_err(rhs.span(), "macro rhs must be delimited"), + _ => { + sess.span_diagnostic.span_err(rhs.span(), "macro rhs must be delimited"); + } } false } diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index aefbec0e518fa..a5afb7aa4fa4e 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -31,8 +31,7 @@ impl base::ProcMacro for BangProcMacro { if let Some(s) = e.as_str() { err.help(&format!("message: {}", s)); } - err.emit(); - ErrorGuaranteed + err.emit() }) } } @@ -58,8 +57,7 @@ impl base::AttrProcMacro for AttrProcMacro { if let Some(s) = e.as_str() { err.help(&format!("message: {}", s)); } - err.emit(); - ErrorGuaranteed + err.emit() }) } } diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index ed7ec51d6298b..b13f0b0d3dad8 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -225,12 +225,12 @@ pub fn prepare_session_directory( let crate_dir = match crate_dir.canonicalize() { Ok(v) => v, Err(err) => { - sess.err(&format!( + let reported = sess.err(&format!( "incremental compilation: error canonicalizing path `{}`: {}", crate_dir.display(), err )); - return Err(ErrorGuaranteed); + return Err(reported); } }; @@ -489,14 +489,14 @@ fn create_dir(sess: &Session, path: &Path, dir_tag: &str) -> Result<(), ErrorGua Ok(()) } Err(err) => { - sess.err(&format!( + let reported = sess.err(&format!( "Could not create incremental compilation {} \ directory `{}`: {}", dir_tag, path.display(), err )); - Err(ErrorGuaranteed) + Err(reported) } } } @@ -545,8 +545,7 @@ fn lock_directory( ); } } - err.emit(); - Err(ErrorGuaranteed) + Err(err.emit()) } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index 0d6dbd8f34398..7721e00c141d7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -147,8 +147,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { self.suggest_adding_lifetime_params(sub, ty_sup, ty_sub, &mut err); - err.emit(); - Some(ErrorGuaranteed) + let reported = err.emit(); + Some(reported) } fn suggest_adding_lifetime_params( diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index 4710eae6189a5..467054e318be5 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -98,7 +98,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let impl_span = self.tcx().def_span(*impl_def_id); err.span_note(impl_span, "...does not necessarily outlive the static lifetime introduced by the compatible `impl`"); } - err.emit(); - Some(ErrorGuaranteed) + let reported = err.emit(); + Some(reported) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs index c7bfa686c04dc..df81aea6ef9ec 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs @@ -54,10 +54,7 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> { pub fn try_report(&self) -> Option { self.try_report_from_nll() - .map(|mut diag| { - diag.emit(); - ErrorGuaranteed - }) + .map(|mut diag| diag.emit()) .or_else(|| self.try_report_impl_not_conforming_to_trait()) .or_else(|| self.try_report_anon_anon_conflict()) .or_else(|| self.try_report_static_impl_trait()) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 99dd418015b14..4fcdcb6366683 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -84,8 +84,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ), ); if self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt) { - err.emit(); - return Some(ErrorGuaranteed); + let reported = err.emit(); + return Some(reported); } else { err.cancel(); } @@ -276,8 +276,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { Some((param.param_ty_span, param.param_ty.to_string())), ); - err.emit(); - Some(ErrorGuaranteed) + let reported = err.emit(); + Some(reported) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 3f0f50bb75af1..b1a42ee66c920 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -33,13 +33,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ) = (sub_trace.values.ty(), sup_trace.values.ty(), sub_trace.cause.code()) && sup_expected_found == sub_expected_found { - self.emit_err( + let guar = self.emit_err( var_origin.span(), sub_expected, sub_found, *trait_item_def_id, ); - return Some(ErrorGuaranteed); + return Some(guar); } if let RegionResolutionError::ConcreteFailure(origin, _, _) | RegionResolutionError::GenericBoundFailure(origin, _, _) = error.clone() @@ -49,18 +49,24 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { trait_item_def_id, } = origin { - self.emit_associated_type_err( + let guar = self.emit_associated_type_err( span, self.infcx.tcx.item_name(impl_item_def_id), impl_item_def_id, trait_item_def_id, ); - return Some(ErrorGuaranteed); + return Some(guar); } None } - fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, trait_def_id: DefId) { + fn emit_err( + &self, + sp: Span, + expected: Ty<'tcx>, + found: Ty<'tcx>, + trait_def_id: DefId, + ) -> ErrorGuaranteed { let trait_sp = self.tcx().def_span(trait_def_id); let mut err = self .tcx() @@ -142,7 +148,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { argument, the other inputs and its output", ); } - err.emit(); + err.emit() } fn emit_associated_type_err( @@ -151,7 +157,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { item_name: Symbol, impl_item_def_id: DefId, trait_item_def_id: DefId, - ) { + ) -> ErrorGuaranteed { let impl_sp = self.tcx().def_span(impl_item_def_id); let trait_sp = self.tcx().def_span(trait_item_def_id); let mut err = self @@ -161,7 +167,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { err.span_label(impl_sp, "found"); err.span_label(trait_sp, "expected"); - err.emit(); + err.emit() } } diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 0224aba01ef28..5d8cc94e05c29 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -189,7 +189,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { self.tcx.sess.delay_span_bug( origin.span(), &format!("no region-bound-pairs for {:?}", body_id), - ) + ); } } } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 1aceb4e95e613..4f30e78f5e2aa 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -373,7 +373,7 @@ pub fn configure_and_expand( if recursion_limit_hit { // If we hit a recursion limit, exit early to avoid later passes getting overwhelmed // with a large AST - Err(ErrorGuaranteed) + Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()) } else { Ok(krate) } @@ -413,7 +413,7 @@ pub fn configure_and_expand( ); msg.warn("The generated documentation may be incorrect"); - msg.emit() + msg.emit(); } else { krate = sess.time("maybe_create_a_macro_crate", || { let is_test_crate = sess.opts.test; @@ -742,29 +742,30 @@ pub fn prepare_outputs( if let Some(ref input_path) = compiler.input_path { if sess.opts.will_create_output_file() { if output_contains_path(&output_paths, input_path) { - sess.err(&format!( + let reported = sess.err(&format!( "the input file \"{}\" would be overwritten by the generated \ executable", input_path.display() )); - return Err(ErrorGuaranteed); + return Err(reported); } if let Some(dir_path) = output_conflicts_with_dir(&output_paths) { - sess.err(&format!( + let reported = sess.err(&format!( "the generated executable for the input file \"{}\" conflicts with the \ existing directory \"{}\"", input_path.display(), dir_path.display() )); - return Err(ErrorGuaranteed); + return Err(reported); } } } if let Some(ref dir) = compiler.temps_dir { if fs::create_dir_all(dir).is_err() { - sess.err("failed to find or create the directory specified by `--temps-dir`"); - return Err(ErrorGuaranteed); + let reported = + sess.err("failed to find or create the directory specified by `--temps-dir`"); + return Err(reported); } } @@ -776,8 +777,9 @@ pub fn prepare_outputs( if !only_dep_info { if let Some(ref dir) = compiler.output_dir { if fs::create_dir_all(dir).is_err() { - sess.err("failed to find or create the directory specified by `--out-dir`"); - return Err(ErrorGuaranteed); + let reported = + sess.err("failed to find or create the directory specified by `--out-dir`"); + return Err(reported); } } } @@ -987,8 +989,8 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { // lot of annoying errors in the ui tests (basically, // lint warnings and so on -- kindck used to do this abort, but // kindck is gone now). -nmatsakis - if sess.has_errors() { - return Err(ErrorGuaranteed); + if let Some(reported) = sess.has_errors() { + return Err(reported); } sess.time("misc_checking_3", || { diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index d0e533b457159..6373f4e9af190 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -5,7 +5,6 @@ use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal}; -use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::LOCAL_CRATE; use rustc_incremental::DepGraphFuture; use rustc_lint::LintStore; @@ -121,10 +120,8 @@ impl<'tcx> Queries<'tcx> { pub fn parse(&self) -> Result<&Query> { self.parse.compute(|| { - passes::parse(self.session(), &self.compiler.input).map_err(|mut parse_error| { - parse_error.emit(); - ErrorGuaranteed - }) + passes::parse(self.session(), &self.compiler.input) + .map_err(|mut parse_error| parse_error.emit()) }) } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 47de4c9be26fe..50a3df21a3bc9 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -157,7 +157,7 @@ impl BoxPointers { if let GenericArgKind::Type(leaf_ty) = leaf.unpack() { if leaf_ty.is_box() { cx.struct_span_lint(BOX_POINTERS, span, |lint| { - lint.build(&format!("type uses owned (Box type) pointers: {}", ty)).emit() + lint.build(&format!("type uses owned (Box type) pointers: {}", ty)).emit(); }); } } @@ -318,7 +318,7 @@ impl UnsafeCode { &self, cx: &EarlyContext<'_>, span: Span, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { // This comes from a macro that has `#[allow_internal_unsafe]`. if span.allows_unsafe() { @@ -350,7 +350,7 @@ impl EarlyLintPass for UnsafeCode { macros using unsafe without triggering \ the `unsafe_code` lint at their call site", ) - .emit() + .emit(); }); } } @@ -360,7 +360,7 @@ impl EarlyLintPass for UnsafeCode { // Don't warn about generated blocks; that'll just pollute the output. if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) { self.report_unsafe(cx, blk.span, |lint| { - lint.build("usage of an `unsafe` block").emit() + lint.build("usage of an `unsafe` block").emit(); }); } } @@ -370,12 +370,12 @@ impl EarlyLintPass for UnsafeCode { match it.kind { ast::ItemKind::Trait(box ast::Trait { unsafety: ast::Unsafe::Yes(_), .. }) => self .report_unsafe(cx, it.span, |lint| { - lint.build("declaration of an `unsafe` trait").emit() + lint.build("declaration of an `unsafe` trait").emit(); }), ast::ItemKind::Impl(box ast::Impl { unsafety: ast::Unsafe::Yes(_), .. }) => self .report_unsafe(cx, it.span, |lint| { - lint.build("implementation of an `unsafe` trait").emit() + lint.build("implementation of an `unsafe` trait").emit(); }), ast::ItemKind::Fn(..) => { @@ -450,7 +450,9 @@ impl EarlyLintPass for UnsafeCode { FnCtxt::Assoc(_) if body.is_none() => "declaration of an `unsafe` method", FnCtxt::Assoc(_) => "implementation of an `unsafe` method", }; - self.report_unsafe(cx, span, |lint| lint.build(msg).emit()); + self.report_unsafe(cx, span, |lint| { + lint.build(msg).emit(); + }); } } } @@ -559,7 +561,7 @@ impl MissingDoc { MISSING_DOCS, cx.tcx.sess.source_map().guess_head_span(sp), |lint| { - lint.build(&format!("missing documentation for {} {}", article, desc)).emit() + lint.build(&format!("missing documentation for {} {}", article, desc)).emit(); }, ); } @@ -777,7 +779,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { "type could implement `Copy`; consider adding `impl \ Copy`", ) - .emit() + .emit(); }) } } @@ -858,7 +860,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations { or a manual implementation", cx.tcx.def_path_str(debug) )) - .emit() + .emit(); }); } } @@ -1278,7 +1280,9 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes { if to_mt == hir::Mutability::Mut && from_mt == hir::Mutability::Not { let msg = "transmuting &T to &mut T is undefined behavior, \ even if the reference is unused, consider instead using an UnsafeCell"; - cx.struct_span_lint(MUTABLE_TRANSMUTES, expr.span, |lint| lint.build(msg).emit()); + cx.struct_span_lint(MUTABLE_TRANSMUTES, expr.span, |lint| { + lint.build(msg).emit(); + }); } } @@ -1328,7 +1332,7 @@ impl<'tcx> LateLintPass<'tcx> for UnstableFeatures { if let Some(items) = attr.meta_item_list() { for item in items { cx.struct_span_lint(UNSTABLE_FEATURES, item.span(), |lint| { - lint.build("unstable feature").emit() + lint.build("unstable feature").emit(); }); } } @@ -1680,7 +1684,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { or lifetime parameters", predicate_kind_name, predicate )) - .emit() + .emit(); }); } } @@ -1915,7 +1919,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnameableTestItems { let attrs = cx.tcx.hir().attrs(it.hir_id()); if let Some(attr) = cx.sess().find_by_name(attrs, sym::rustc_test_marker) { cx.struct_span_lint(UNNAMEABLE_TEST_ITEMS, attr.span, |lint| { - lint.build("cannot test inner items").emit() + lint.build("cannot test inner items").emit(); }); } } @@ -2040,7 +2044,7 @@ impl KeywordIdents { format!("r#{}", ident), Applicability::MachineApplicable, ) - .emit() + .emit(); }); } } @@ -3055,7 +3059,7 @@ impl<'tcx> LateLintPass<'tcx> for ClashingExternDeclarations { "this signature doesn't match the previous declaration", ) .note_expected_found(&"", expected_str, &"", found_str) - .emit() + .emit(); }, ); } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index d3c019ad70e3c..882fa4496ca26 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -593,7 +593,7 @@ pub trait LintContext: Sized { &self, lint: &'static Lint, span: Option>, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), diagnostic: BuiltinLintDiagnostics, ) { self.lookup(lint, span, |lint| { @@ -840,19 +840,23 @@ pub trait LintContext: Sized { &self, lint: &'static Lint, span: Option, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ); fn struct_span_lint>( &self, lint: &'static Lint, span: S, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { self.lookup(lint, Some(span), decorate); } /// Emit a lint at the appropriate level, with no associated span. - fn lint(&self, lint: &'static Lint, decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>)) { + fn lint( + &self, + lint: &'static Lint, + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + ) { self.lookup(lint, None as Option, decorate); } } @@ -893,7 +897,7 @@ impl LintContext for LateContext<'_> { &self, lint: &'static Lint, span: Option, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { let hir_id = self.last_node_with_lint_attrs; @@ -920,7 +924,7 @@ impl LintContext for EarlyContext<'_> { &self, lint: &'static Lint, span: Option, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { self.builder.struct_lint(lint, span.map(|s| s.into()), decorate) } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index e9b7620bf1d7f..7447f9f64b7b1 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -45,7 +45,9 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { self.context.lookup_with_diagnostics( lint_id.lint, Some(span), - |lint| lint.build(&msg).emit(), + |lint| { + lint.build(&msg).emit(); + }, diagnostic, ); } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 0d790e3820608..99a5720832e88 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -652,7 +652,7 @@ impl<'s> LintLevelsBuilder<'s> { &self, lint: &'static Lint, span: Option, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { let (level, src) = self.lint_level(lint); struct_lint_level(self.sess, lint, level, src, span, decorate) diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index 264a80339ccdb..6182d2b10ed5b 100644 --- a/compiler/rustc_lint/src/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs @@ -180,13 +180,13 @@ impl EarlyLintPass for NonAsciiIdents { } has_non_ascii_idents = true; cx.struct_span_lint(NON_ASCII_IDENTS, sp, |lint| { - lint.build("identifier contains non-ASCII characters").emit() + lint.build("identifier contains non-ASCII characters").emit(); }); if check_uncommon_codepoints && !symbol_str.chars().all(GeneralSecurityProfile::identifier_allowed) { cx.struct_span_lint(UNCOMMON_CODEPOINTS, sp, |lint| { - lint.build("identifier contains uncommon Unicode codepoints").emit() + lint.build("identifier contains uncommon Unicode codepoints").emit(); }) } } @@ -337,7 +337,7 @@ impl EarlyLintPass for NonAsciiIdents { let char_info = format!("'{}' (U+{:04X})", ch, ch as u32); note += &char_info; } - lint.build(&message).note(¬e).note("please recheck to make sure their usages are indeed what you want").emit() + lint.build(&message).note(¬e).note("please recheck to make sure their usages are indeed what you want").emit(); }); } } diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index 39b5b7afdaef1..5d734fd2ba705 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { let method = &call.ident.name; let message = format!("call to `.{}()` on a reference in this situation does nothing", &method,); - lint.build(&message).span_label(span, "unnecessary method call").note(¬e).emit() + lint.build(&message).span_label(span, "unnecessary method call").note(¬e).emit(); }); } } diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index 4c7f3482776d7..5b6997bf0eeaf 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -113,7 +113,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { predicate, cx.tcx.def_path_str(needs_drop) ); - lint.build(&msg).emit() + lint.build(&msg).emit(); }); } } @@ -135,7 +135,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { instead using `{}` to detect whether a type is trivially dropped", cx.tcx.def_path_str(needs_drop) ); - lint.build(&msg).emit() + lint.build(&msg).emit(); }); } } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index ed5578c754dd5..c95905b9b1851 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -441,7 +441,7 @@ fn lint_uint_literal<'tcx>( min, max, )) - .emit() + .emit(); }); } } @@ -502,7 +502,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { hir::ExprKind::Binary(binop, ref l, ref r) => { if is_comparison(binop) && !check_limits(cx, binop, &l, &r) { cx.struct_span_lint(UNUSED_COMPARISONS, e.span, |lint| { - lint.build("comparison is useless due to type limits").emit() + lint.build("comparison is useless due to type limits").emit(); }); } } @@ -1382,7 +1382,7 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences { larger ({} bytes) than the next largest", largest )) - .emit() + .emit(); }, ); } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index abe34a8a39f14..91b72f1d2b17e 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -170,7 +170,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { if !(type_permits_lack_of_use || fn_warned || op_warned) { cx.struct_span_lint(UNUSED_RESULTS, s.span, |lint| { - lint.build(&format!("unused result of type `{}`", ty)).emit() + lint.build(&format!("unused result of type `{}`", ty)).emit(); }); } @@ -368,9 +368,9 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements { } else { lint.span_help(s.span, "use `drop` to clarify the intent"); } - lint.emit() + lint.emit(); } else { - lint.build("path statement with no effect").emit() + lint.build("path statement with no effect").emit(); } }); } @@ -1111,7 +1111,7 @@ impl UnusedImportBraces { }; cx.struct_span_lint(UNUSED_IMPORT_BRACES, item.span, |lint| { - lint.build(&format!("braces around {} is unnecessary", node_name)).emit() + lint.build(&format!("braces around {} is unnecessary", node_name)).emit(); }); } } @@ -1170,7 +1170,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation { "unnecessary allocation, use `&mut` instead" } }; - lint.build(msg).emit() + lint.build(msg).emit(); }); } } diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index f667aec03c577..a9e3b55aeeedf 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -825,11 +825,13 @@ impl<'a> CrateLoader<'a> { for (_, data) in self.cstore.iter_crate_data() { if data.has_global_allocator() { match global_allocator { - Some(other_crate) => self.sess.err(&format!( + Some(other_crate) => { + self.sess.err(&format!( "the `#[global_allocator]` in {} conflicts with global allocator in: {}", other_crate, data.name() - )), + )); + } None => global_allocator = Some(data.name()), } } @@ -864,7 +866,7 @@ impl<'a> CrateLoader<'a> { // don't perform this validation if the session has errors, as one of // those errors may indicate a circular dependency which could cause // this to stack overflow. - if self.sess.has_errors() { + if self.sess.has_errors().is_some() { return; } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index f4bc28f4da199..c3a7611239139 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -145,41 +145,49 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> { ("bundle", NativeLibKind::Static { bundle, .. }) => { *bundle = Some(value); } - ("bundle", _) => sess.span_err( - span, - "bundle linking modifier is only compatible with \ + ("bundle", _) => { + sess.span_err( + span, + "bundle linking modifier is only compatible with \ `static` linking kind", - ), + ); + } ("verbatim", _) => lib.verbatim = Some(value), ("whole-archive", NativeLibKind::Static { whole_archive, .. }) => { *whole_archive = Some(value); } - ("whole-archive", _) => sess.span_err( - span, - "whole-archive linking modifier is only compatible with \ + ("whole-archive", _) => { + sess.span_err( + span, + "whole-archive linking modifier is only compatible with \ `static` linking kind", - ), + ); + } ("as-needed", NativeLibKind::Dylib { as_needed }) | ("as-needed", NativeLibKind::Framework { as_needed }) => { *as_needed = Some(value); } - ("as-needed", _) => sess.span_err( - span, - "as-needed linking modifier is only compatible with \ + ("as-needed", _) => { + sess.span_err( + span, + "as-needed linking modifier is only compatible with \ `dylib` and `framework` linking kinds", - ), + ); + } - _ => sess.span_err( - span, - &format!( - "unrecognized linking modifier `{}`, expected one \ + _ => { + sess.span_err( + span, + &format!( + "unrecognized linking modifier `{}`, expected one \ of: bundle, verbatim, whole-archive, as-needed", - modifier - ), - ), + modifier + ), + ); + } } } } else { @@ -247,7 +255,9 @@ impl Collector<'_> { Some(span) => { struct_span_err!(self.tcx.sess, span, E0455, "{}", msg).emit(); } - None => self.tcx.sess.err(msg), + None => { + self.tcx.sess.err(msg); + } } } if lib.cfg.is_some() && !self.tcx.features().link_cfg { diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 1b301629b9c73..dc1fe5f2b0836 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -2,7 +2,9 @@ use std::cmp; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId}; +use rustc_errors::{ + Diagnostic, DiagnosticBuilder, DiagnosticId, EmissionGuarantee, ErrorGuaranteed, +}; use rustc_hir::HirId; use rustc_index::vec::IndexVec; use rustc_query_system::ich::StableHashingContext; @@ -220,22 +222,28 @@ impl LintExpectation { } } -pub struct LintDiagnosticBuilder<'a>(DiagnosticBuilder<'a, ()>); +pub struct LintDiagnosticBuilder<'a, G: EmissionGuarantee>(DiagnosticBuilder<'a, G>); -impl<'a> LintDiagnosticBuilder<'a> { - /// Return the inner DiagnosticBuilder, first setting the primary message to `msg`. - pub fn build(mut self, msg: &str) -> DiagnosticBuilder<'a, ()> { +impl<'a, G: EmissionGuarantee> LintDiagnosticBuilder<'a, G> { + /// Return the inner `DiagnosticBuilder`, first setting the primary message to `msg`. + pub fn build(mut self, msg: &str) -> DiagnosticBuilder<'a, G> { self.0.set_primary_message(msg); self.0.set_is_lint(); self.0 } - /// Create a LintDiagnosticBuilder from some existing DiagnosticBuilder. - pub fn new(err: DiagnosticBuilder<'a, ()>) -> LintDiagnosticBuilder<'a> { + /// Create a `LintDiagnosticBuilder` from some existing `DiagnosticBuilder`. + pub fn new(err: DiagnosticBuilder<'a, G>) -> LintDiagnosticBuilder<'a, G> { LintDiagnosticBuilder(err) } } +impl<'a> LintDiagnosticBuilder<'a, ErrorGuaranteed> { + pub fn forget_guarantee(self) -> LintDiagnosticBuilder<'a, ()> { + LintDiagnosticBuilder(self.0.forget_guarantee()) + } +} + pub fn explain_lint_level_source( sess: &Session, lint: &'static Lint, @@ -316,7 +324,7 @@ pub fn struct_lint_level<'s, 'd>( level: Level, src: LintLevelSource, span: Option, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>) + 'd, + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>) + 'd, ) { // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to // the "real" work. @@ -326,7 +334,7 @@ pub fn struct_lint_level<'s, 'd>( level: Level, src: LintLevelSource, span: Option, - decorate: Box FnOnce(LintDiagnosticBuilder<'b>) + 'd>, + decorate: Box FnOnce(LintDiagnosticBuilder<'b, ()>) + 'd>, ) { // Check for future incompatibility lints and issue a stronger warning. let future_incompatible = lint.future_incompatible; diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 167a097d9f852..219af6caa1ae1 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -258,7 +258,7 @@ fn late_report_deprecation( let kind = tcx.def_kind(def_id).descr(def_id); deprecation_suggestion(&mut diag, kind, suggestion, method_span); } - diag.emit() + diag.emit(); }); } @@ -483,7 +483,7 @@ impl<'tcx> TyCtxt<'tcx> { ) { let soft_handler = |lint, span, msg: &_| { self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| { - lint.build(msg).emit() + lint.build(msg).emit(); }) }; match self.eval_stability(def_id, id, span, method_span) { diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 2c3c61259c473..492091a4f2540 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -91,7 +91,7 @@ fn print_backtrace(backtrace: &Backtrace) { impl From for InterpErrorInfo<'_> { fn from(err: ErrorHandled) -> Self { match err { - ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted => { + ErrorHandled::Reported(ErrorGuaranteed { .. }) | ErrorHandled::Linted => { err_inval!(ReferencedConstant) } ErrorHandled::TooGeneric => err_inval!(TooGeneric), @@ -160,7 +160,7 @@ impl fmt::Display for InvalidProgramInfo<'_> { match self { TooGeneric => write!(f, "encountered overly generic constant"), ReferencedConstant => write!(f, "referenced constant has errors"), - AlreadyReported(ErrorGuaranteed) => { + AlreadyReported(ErrorGuaranteed { .. }) => { write!(f, "encountered constants with type errors, stopping evaluation") } Layout(ref err) => write!(f, "{}", err), diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 44b622c1e3d86..e07b174bc6aaa 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -252,7 +252,9 @@ rustc_queries! { } /// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`. - query thir_body(key: ty::WithOptConstParam) -> (&'tcx Steal>, thir::ExprId) { + query thir_body(key: ty::WithOptConstParam) + -> Result<(&'tcx Steal>, thir::ExprId), ErrorGuaranteed> + { // Perf tests revealed that hashing THIR is inefficient (see #85729). no_hash desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key.did.to_def_id()) } diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 4ff8e61ee7437..c43ec048c3f99 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -31,12 +31,12 @@ pub struct Graph { pub children: DefIdMap, /// Whether an error was emitted while constructing the graph. - pub has_errored: bool, + pub has_errored: Option, } impl Graph { pub fn new() -> Graph { - Graph { parent: Default::default(), children: Default::default(), has_errored: false } + Graph { parent: Default::default(), children: Default::default(), has_errored: None } } /// The parent of a given impl, which is the `DefId` of the trait when the @@ -246,8 +246,10 @@ pub fn ancestors<'tcx>( ) -> Result, ErrorGuaranteed> { let specialization_graph = tcx.specialization_graph_of(trait_def_id); - if specialization_graph.has_errored || tcx.type_of(start_from_impl).references_error() { - Err(ErrorGuaranteed) + if let Some(reported) = specialization_graph.has_errored { + Err(reported) + } else if let Some(reported) = tcx.type_of(start_from_impl).error_reported() { + Err(reported) } else { Ok(Ancestors { trait_def_id, diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index cad77f6436ea2..cb219c4c4e4c9 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -7,7 +7,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::HashingControls; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; @@ -453,7 +452,7 @@ impl<'tcx> AdtDef<'tcx> { } Err(err) => { let msg = match err { - ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted => { + ErrorHandled::Reported(_) | ErrorHandled::Linted => { "enum discriminant evaluation failed" } ErrorHandled::TooGeneric => "enum discriminant depends on generics", diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index e72828dd52959..4b7c1d44cea29 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -264,7 +264,7 @@ impl<'tcx> Const<'tcx> { if let Some(val) = self.val().try_eval(tcx, param_env) { match val { Ok(val) => Const::from_value(tcx, val, self.ty()), - Err(ErrorGuaranteed) => tcx.const_error(self.ty()), + Err(ErrorGuaranteed { .. }) => tcx.const_error(self.ty()), } } else { self diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 494535f3d597a..f51e6c2bc1f4d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -91,7 +91,10 @@ pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync { /// except through the error-reporting functions on a [`tcx`][TyCtxt]. #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] #[derive(TyEncodable, TyDecodable, HashStable)] -pub struct DelaySpanBugEmitted(()); +pub struct DelaySpanBugEmitted { + pub reported: ErrorGuaranteed, + _priv: (), +} type InternedSet<'tcx, T> = ShardedHashMap, ()>; @@ -1236,8 +1239,8 @@ impl<'tcx> TyCtxt<'tcx> { /// ensure it gets used. #[track_caller] pub fn ty_error_with_message>(self, span: S, msg: &str) -> Ty<'tcx> { - self.sess.delay_span_bug(span, msg); - self.mk_ty(Error(DelaySpanBugEmitted(()))) + let reported = self.sess.delay_span_bug(span, msg); + self.mk_ty(Error(DelaySpanBugEmitted { reported, _priv: () })) } /// Like [TyCtxt::ty_error] but for constants. @@ -1258,8 +1261,11 @@ impl<'tcx> TyCtxt<'tcx> { span: S, msg: &str, ) -> Const<'tcx> { - self.sess.delay_span_bug(span, msg); - self.mk_const(ty::ConstS { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty }) + let reported = self.sess.delay_span_bug(span, msg); + self.mk_const(ty::ConstS { + val: ty::ConstKind::Error(DelaySpanBugEmitted { reported, _priv: () }), + ty, + }) } pub fn consider_optimizing String>(self, msg: T) -> bool { @@ -2733,7 +2739,7 @@ impl<'tcx> TyCtxt<'tcx> { lint: &'static Lint, hir_id: HirId, span: impl Into, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { let (level, src) = self.lint_level_at_node(lint, hir_id); struct_lint_level(self.sess, lint, level, src, Some(span.into()), decorate); @@ -2743,7 +2749,7 @@ impl<'tcx> TyCtxt<'tcx> { self, lint: &'static Lint, id: HirId, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { let (level, src) = self.lint_level_at_node(lint, id); struct_lint_level(self.sess, lint, level, src, None, decorate); diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 4922d07ae1c5d..780d380da365e 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -51,6 +51,7 @@ //! ``` use crate::mir; use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags}; +use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; use rustc_data_structures::fx::FxHashSet; @@ -151,6 +152,13 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { fn references_error(&self) -> bool { self.has_type_flags(TypeFlags::HAS_ERROR) } + fn error_reported(&self) -> Option { + if self.references_error() { + Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) + } else { + None + } + } fn has_param_types_or_consts(&self) -> bool { self.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_CT_PARAM) } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index e12d075efa9b6..ab3dc8f020cc9 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -118,7 +118,9 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ }; let body = tcx.hir().body(body_id); - let (thir, expr) = tcx.thir_body(def); + let (thir, expr) = tcx + .thir_body(def) + .unwrap_or_else(|_| (tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0))); // We ran all queries that depended on THIR at the beginning // of `mir_build`, so now we can steal it let thir = thir.steal(); @@ -229,7 +231,9 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ let return_ty = typeck_results.node_type(id); - let (thir, expr) = tcx.thir_body(def); + let (thir, expr) = tcx + .thir_body(def) + .unwrap_or_else(|_| (tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0))); // We ran all queries that depended on THIR at the beginning // of `mir_build`, so now we can steal it let thir = thir.steal(); diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index a96bb4e03d97a..122af3f621087 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -405,7 +405,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } else { ty::WithOptConstParam::unknown(closure_id) }; - let (closure_thir, expr) = self.tcx.thir_body(closure_def); + let (closure_thir, expr) = self.tcx.thir_body(closure_def).unwrap_or_else(|_| { + (self.tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0)) + }); let closure_thir = &closure_thir.borrow(); let hir_context = self.tcx.hir().local_def_id_to_hir_id(closure_id); let mut closure_visitor = @@ -606,7 +608,10 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam body, + Err(_) => return, + }; let thir = &thir.borrow(); // If `thir` is empty, a type error occurred, skip this body. if thir.exprs.is_empty() { diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index a65a3ed31f638..426596bf13c0a 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -7,6 +7,7 @@ use crate::thir::util::UserAnnotatedTyHelpers; use rustc_ast as ast; use rustc_data_structures::steal::Steal; +use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::HirId; @@ -20,22 +21,25 @@ use rustc_span::Span; crate fn thir_body<'tcx>( tcx: TyCtxt<'tcx>, owner_def: ty::WithOptConstParam, -) -> (&'tcx Steal>, ExprId) { +) -> Result<(&'tcx Steal>, ExprId), ErrorGuaranteed> { let hir = tcx.hir(); let body = hir.body(hir.body_owned_by(hir.local_def_id_to_hir_id(owner_def.did))); let mut cx = Cx::new(tcx, owner_def); - if cx.typeck_results.tainted_by_errors.is_some() { - return (tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0)); + if let Some(reported) = cx.typeck_results.tainted_by_errors { + return Err(reported); } let expr = cx.mirror_expr(&body.value); - (tcx.alloc_steal_thir(cx.thir), expr) + Ok((tcx.alloc_steal_thir(cx.thir), expr)) } crate fn thir_tree<'tcx>( tcx: TyCtxt<'tcx>, owner_def: ty::WithOptConstParam, ) -> String { - format!("{:#?}", thir_body(tcx, owner_def).0.steal()) + match thir_body(tcx, owner_def) { + Ok((thir, _)) => format!("{:#?}", thir.steal()), + Err(_) => "error".into(), + } } struct Cx<'tcx> { diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index ae9b44cee4bf8..dd7d4e3e514cd 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -194,7 +194,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::INDIRECT_STRUCTURAL_MATCH, self.id, self.span, - |lint| lint.build(&msg).emit(), + |lint| { + lint.build(&msg).emit(); + }, ); } else { debug!( @@ -272,7 +274,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, id, span, - |lint| lint.build("floating-point types cannot be used in patterns").emit(), + |lint| { + lint.build("floating-point types cannot be used in patterns").emit(); + }, ); } PatKind::Constant { value: cv } @@ -284,7 +288,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { if self.include_lint_checks { tcx.sess.span_err(span, msg); } else { - tcx.sess.delay_span_bug(span, msg) + tcx.sess.delay_span_bug(span, msg); } PatKind::Wild } @@ -301,7 +305,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { if self.include_lint_checks { tcx.sess.span_err(self.span, &msg); } else { - tcx.sess.delay_span_bug(self.span, &msg) + tcx.sess.delay_span_bug(self.span, &msg); } PatKind::Wild } @@ -331,7 +335,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { cv.ty(), cv.ty(), ); - lint.build(&msg).emit() + lint.build(&msg).emit(); }, ); } @@ -356,7 +360,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { if self.include_lint_checks { tcx.sess.span_err(span, &msg); } else { - tcx.sess.delay_span_bug(span, &msg) + tcx.sess.delay_span_bug(span, &msg); } PatKind::Wild } @@ -393,7 +397,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { if self.include_lint_checks { tcx.sess.span_err(span, &msg); } else { - tcx.sess.delay_span_bug(span, &msg) + tcx.sess.delay_span_bug(span, &msg); } PatKind::Wild } @@ -471,7 +475,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::INDIRECT_STRUCTURAL_MATCH, self.id, self.span, - |lint| lint.build(&msg).emit(), + |lint| {lint.build(&msg).emit();}, ); } PatKind::Constant { value: cv } @@ -482,7 +486,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { if self.include_lint_checks { tcx.sess.span_err(span, &msg); } else { - tcx.sess.delay_span_bug(span, &msg) + tcx.sess.delay_span_bug(span, &msg); } } PatKind::Wild @@ -539,7 +543,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::POINTER_STRUCTURAL_MATCH, id, span, - |lint| lint.build(&msg).emit(), + |lint| { + lint.build(&msg).emit(); + }, ); } PatKind::Constant { value: cv } @@ -550,7 +556,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { if self.include_lint_checks { tcx.sess.span_err(span, &msg); } else { - tcx.sess.delay_span_bug(span, &msg) + tcx.sess.delay_span_bug(span, &msg); } PatKind::Wild } @@ -575,7 +581,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::NONTRIVIAL_STRUCTURAL_MATCH, id, span, - |lint| lint.build(&msg).emit(), + |lint| { + lint.build(&msg).emit(); + }, ); } diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs index 8731669b10958..097a6186cd57a 100644 --- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs +++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs @@ -64,7 +64,7 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> { place: &Place<'tcx>, const_item: DefId, location: Location, - decorate: impl for<'b> FnOnce(LintDiagnosticBuilder<'b>) -> DiagnosticBuilder<'b, ()>, + decorate: impl for<'b> FnOnce(LintDiagnosticBuilder<'b, ()>) -> DiagnosticBuilder<'b, ()>, ) { // Don't lint on borrowing/assigning when a dereference is involved. // If we 'leave' the temporary via a dereference, we must @@ -88,7 +88,7 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> { |lint| { decorate(lint) .span_note(self.tcx.def_span(const_item), "`const` item defined here") - .emit() + .emit(); }, ); } diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index 23d59c8007135..f0367958ef8c5 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -46,7 +46,7 @@ fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) { does not derive Copy (error E0133)" .to_string() }; - lint.build(&message).emit() + lint.build(&message).emit(); }); } @@ -110,7 +110,7 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> { reference with a raw pointer and use `read_unaligned`/`write_unaligned` \ (loads and stores via `*p` must be properly aligned even when using raw pointers)" ) - .emit() + .emit(); }, ); } diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 34c539f319194..5ed33ab9fec17 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -538,7 +538,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { self.tcx.struct_span_lint_hir(lint, lint_root, source_info.span, |lint| { let mut err = lint.build(message); err.span_label(source_info.span, format!("{:?}", panic)); - err.emit() + err.emit(); }); } } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index ed771534c4c4c..a9dcc484b9e8d 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -180,7 +180,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator}; -use rustc_errors::{ErrorGuaranteed, FatalError}; +use rustc_errors::FatalError; use rustc_hir as hir; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; @@ -716,9 +716,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { match self.tcx.const_eval_resolve(param_env, ct, None) { // The `monomorphize` call should have evaluated that constant already. Ok(val) => val, - Err(ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted) => { - return; - } + Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return, Err(ErrorHandled::TooGeneric) => span_bug!( self.body.source_info(location).span, "collection encountered polymorphic constant: {:?}", @@ -750,7 +748,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { substituted_constant, val ), - Err(ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted) => {} + Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => {} Err(ErrorHandled::TooGeneric) => span_bug!( self.body.source_info(location).span, "collection encountered polymorphic constant: {}", @@ -864,7 +862,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { |lint| { let mut err = lint.build(&format!("moving {} bytes", layout.size.bytes())); err.span_label(source_info.span, "value moved from here"); - err.emit() + err.emit(); }, ); } diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index c7d166319eac8..bec4561928cc2 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -202,7 +202,7 @@ pub(crate) fn emit_unescape_error( diag.emit(); } EscapeError::TooShortHexEscape => { - handler.span_err(span, "numeric character escape is too short") + handler.span_err(span, "numeric character escape is too short"); } EscapeError::InvalidCharInHexEscape | EscapeError::InvalidCharInUnicodeEscape => { let (c, span) = last_char(); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index b582f060395c3..4d5c552b81bb1 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -212,10 +212,10 @@ impl<'a> Parser<'a> { if let Err(mut e) = self.expect_semi() { match tree.kind { UseTreeKind::Glob => { - e.note("the wildcard token must be last on the path").emit(); + e.note("the wildcard token must be last on the path"); } UseTreeKind::Nested(..) => { - e.note("glob-like brace syntax must be last on the path").emit(); + e.note("glob-like brace syntax must be last on the path"); } _ => (), } @@ -1485,7 +1485,7 @@ impl<'a> Parser<'a> { // Make sure an error was emitted (either by recovering an angle bracket, // or by finding an identifier as the next token), since we're // going to continue parsing - assert!(self.sess.span_diagnostic.has_errors()); + assert!(self.sess.span_diagnostic.has_errors().is_some()); } else { return Err(err); } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 06184b4797255..ebf6678d3ad37 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -169,7 +169,7 @@ impl CheckAttrVisitor<'_> { } ast::AttrStyle::Inner => "crate-level attribute should be in the root module", }; - lint.build(msg).emit() + lint.build(msg).emit(); }); } } @@ -236,7 +236,7 @@ impl CheckAttrVisitor<'_> { | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { - lint.build("`#[inline]` is ignored on function prototypes").emit() + lint.build("`#[inline]` is ignored on function prototypes").emit(); }); true } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index ea99a90e937c3..7298aba7e8763 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1588,7 +1588,7 @@ impl<'tcx> Liveness<'_, 'tcx> { shorthands, Applicability::MachineApplicable, ); - err.emit() + err.emit(); }, ); } else { @@ -1611,7 +1611,7 @@ impl<'tcx> Liveness<'_, 'tcx> { non_shorthands, Applicability::MachineApplicable, ); - err.emit() + err.emit(); }, ); } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index f36a1f61aaccb..09be1dac6f163 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -128,7 +128,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { String::new(), rustc_errors::Applicability::MachineApplicable, ) - .emit() + .emit(); }); } @@ -728,10 +728,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { INEFFECTIVE_UNSTABLE_TRAIT_IMPL, item.hir_id(), span, - |lint| lint + |lint| {lint .build("an `#[unstable]` annotation here has no effect") .note("see issue #55436 for more information") - .emit() + .emit();} ); } } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index fdda77d01b3fe..1f286d557ca0b 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1742,7 +1742,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { descr, self.tcx.crate_name(def_id.krate) )) - .emit() + .emit(); }, ); } @@ -1786,7 +1786,9 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { lint::builtin::PRIVATE_IN_PUBLIC, hir_id, span, - |lint| lint.build(&format!("{} (error {})", make_msg(), err_code)).emit(), + |lint| { + lint.build(&format!("{} (error {})", make_msg(), err_code)).emit(); + }, ); } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 8dec28c8ae283..1394f4083d0b9 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1997,7 +1997,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { Vec::new(), &[], ); - db.emit() + db.emit(); }, ); } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 1997f2133ed00..7e743481a51fc 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -3143,10 +3143,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { for bound in lifetime_i.bounds { match bound { hir::GenericBound::Outlives(ref lt) => match lt.name { - hir::LifetimeName::Underscore => self.tcx.sess.delay_span_bug( - lt.span, - "use of `'_` in illegal place, but not caught by lowering", - ), + hir::LifetimeName::Underscore => { + self.tcx.sess.delay_span_bug( + lt.span, + "use of `'_` in illegal place, but not caught by lowering", + ); + } hir::LifetimeName::Static => { self.insert_lifetime(lt, Region::Static); self.tcx @@ -3172,7 +3174,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { lt.span, "lowering generated `ImplicitObjectLifetimeDefault` \ outside of an object type", - ) + ); } hir::LifetimeName::Error => { // No need to do anything, error already reported. diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index bca19e84cf875..7f696da86f20e 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -100,7 +100,7 @@ pub fn validate_crate_name(sess: &Session, s: &str, sp: Option) { match sp { Some(sp) => sess.span_err(sp, s), None => sess.err(s), - } + }; err_count += 1; }; if s.is_empty() { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index eabebfcf3eae5..7eeb6f90f99d9 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -262,7 +262,7 @@ impl Session { } diag.emit(); // If we should err, make sure we did. - if must_err && !self.has_errors() { + if must_err && !self.has_errors().is_some() { // We have skipped a feature gate, and not run into other errors... reject. self.err( "`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \ @@ -404,13 +404,13 @@ impl Session { self.span_err(sp, msg); } } - pub fn span_err>(&self, sp: S, msg: &str) { + pub fn span_err>(&self, sp: S, msg: &str) -> ErrorGuaranteed { self.diagnostic().span_err(sp, msg) } pub fn span_err_with_code>(&self, sp: S, msg: &str, code: DiagnosticId) { self.diagnostic().span_err_with_code(sp, &msg, code) } - pub fn err(&self, msg: &str) { + pub fn err(&self, msg: &str) -> ErrorGuaranteed { self.diagnostic().err(msg) } pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed { @@ -420,7 +420,7 @@ impl Session { pub fn err_count(&self) -> usize { self.diagnostic().err_count() } - pub fn has_errors(&self) -> bool { + pub fn has_errors(&self) -> Option { self.diagnostic().has_errors() } pub fn has_errors_or_delayed_span_bugs(&self) -> bool { @@ -430,9 +430,9 @@ impl Session { self.diagnostic().abort_if_errors(); } pub fn compile_status(&self) -> Result<(), ErrorGuaranteed> { - if self.diagnostic().has_errors_or_lint_errors() { - self.diagnostic().emit_stashed_diagnostics(); - Err(ErrorGuaranteed) + if let Some(reported) = self.diagnostic().has_errors_or_lint_errors() { + let _ = self.diagnostic().emit_stashed_diagnostics(); + Err(reported) } else { Ok(()) } @@ -444,7 +444,11 @@ impl Session { { let old_count = self.err_count(); let result = f(); - if self.err_count() == old_count { Ok(result) } else { Err(ErrorGuaranteed) } + if self.err_count() == old_count { + Ok(result) + } else { + Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()) + } } pub fn span_warn>(&self, sp: S, msg: &str) { self.diagnostic().span_warn(sp, msg) @@ -457,7 +461,7 @@ impl Session { } /// Delay a span_bug() call until abort_if_errors() #[track_caller] - pub fn delay_span_bug>(&self, sp: S, msg: &str) { + pub fn delay_span_bug>(&self, sp: S, msg: &str) -> ErrorGuaranteed { self.diagnostic().delay_span_bug(sp, msg) } @@ -1387,12 +1391,18 @@ fn validate_commandline_args_with_session_available(sess: &Session) { let unsupported_sanitizers = sess.opts.debugging_opts.sanitizer - supported_sanitizers; match unsupported_sanitizers.into_iter().count() { 0 => {} - 1 => sess - .err(&format!("{} sanitizer is not supported for this target", unsupported_sanitizers)), - _ => sess.err(&format!( - "{} sanitizers are not supported for this target", - unsupported_sanitizers - )), + 1 => { + sess.err(&format!( + "{} sanitizer is not supported for this target", + unsupported_sanitizers + )); + } + _ => { + sess.err(&format!( + "{} sanitizers are not supported for this target", + unsupported_sanitizers + )); + } } // Cannot mix and match sanitizers. let mut sanitizer_iter = sess.opts.debugging_opts.sanitizer.into_iter(); @@ -1446,7 +1456,7 @@ pub enum IncrCompSession { InvalidBecauseOfErrors { session_directory: PathBuf }, } -pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) { +pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) -> ErrorGuaranteed { let emitter: Box = match output { config::ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); @@ -1457,7 +1467,8 @@ pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) { } }; let handler = rustc_errors::Handler::with_emitter(true, None, emitter); - handler.struct_fatal(msg).emit(); + let reported = handler.struct_fatal(msg).emit(); + reported } pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs index 3e0c8234edafb..a607fb6c1b87c 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen.rs @@ -51,7 +51,7 @@ pub fn codegen_fulfill_obligation<'tcx>( // leading to an ambiguous result. So report this as an // overflow bug, since I believe this is the only case // where ambiguity can result. - infcx.tcx.sess.delay_span_bug( + let reported = infcx.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, &format!( "encountered ambiguity selecting `{:?}` during codegen, presuming due to \ @@ -59,21 +59,21 @@ pub fn codegen_fulfill_obligation<'tcx>( trait_ref ), ); - return Err(ErrorGuaranteed); + return Err(reported); } Err(Unimplemented) => { // This can trigger when we probe for the source of a `'static` lifetime requirement // on a trait object: `impl Foo for dyn Trait {}` has an implicit `'static` bound. // This can also trigger when we have a global bound that is not actually satisfied, // but was included during typeck due to the trivial_bounds feature. - infcx.tcx.sess.delay_span_bug( + let guar = infcx.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, &format!( "Encountered error `Unimplemented` selecting `{:?}` during codegen", trait_ref ), ); - return Err(ErrorGuaranteed); + return Err(guar); } Err(e) => { bug!("Encountered error `{:?}` selecting `{:?}` during codegen", e, trait_ref) diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index f880b28b3c8dc..40a39c4cfc2e3 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -18,7 +18,7 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::thir; use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable}; use rustc_middle::ty::subst::{Subst, SubstsRef}; -use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, DelaySpanBugEmitted, TyCtxt, TypeFoldable}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::Span; @@ -177,8 +177,9 @@ pub fn is_const_evaluatable<'cx, 'tcx>( false => NotConstEvaluatable::MentionsParam, }), Err(ErrorHandled::Linted) => { - infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); - Err(NotConstEvaluatable::Error(ErrorGuaranteed)) + let reported = + infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); + Err(NotConstEvaluatable::Error(reported)) } Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), Ok(_) => Ok(()), @@ -244,7 +245,7 @@ impl<'tcx> AbstractConst<'tcx> { ) -> Result>, ErrorGuaranteed> { match ct.val() { ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.shrink()), - ty::ConstKind::Error(_) => Err(ErrorGuaranteed), + ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => Err(reported), _ => Ok(None), } } @@ -280,17 +281,19 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { } fn error(&mut self, span: Span, msg: &str) -> Result { - self.tcx + let reported = self + .tcx .sess .struct_span_err(self.root_span(), "overly complex generic constant") .span_label(span, msg) .help("consider moving this anonymous constant into a `const` function") .emit(); - Err(ErrorGuaranteed) + Err(reported) } fn maybe_supported_error(&mut self, span: Span, msg: &str) -> Result { - self.tcx + let reported = self + .tcx .sess .struct_span_err(self.root_span(), "overly complex generic constant") .span_label(span, msg) @@ -298,7 +301,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { .note("this operation may be supported in the future") .emit(); - Err(ErrorGuaranteed) + Err(reported) } fn new( @@ -553,11 +556,7 @@ pub(super) fn thir_abstract_const<'tcx>( _ => return Ok(None), } - let body = tcx.thir_body(def); - if body.0.borrow().exprs.is_empty() { - // type error in constant, there is no thir - return Err(ErrorGuaranteed); - } + let body = tcx.thir_body(def)?; AbstractConstBuilder::new(tcx, (&*body.0.borrow(), body.1))? .map(AbstractConstBuilder::build) @@ -580,7 +579,7 @@ pub(super) fn try_unify_abstract_consts<'tcx>( Ok(false) })() - .unwrap_or_else(|ErrorGuaranteed| true) + .unwrap_or_else(|_: ErrorGuaranteed| true) // FIXME(generic_const_exprs): We should instead have this // method return the resulting `ty::Const` and return `ConstKind::Error` // on `ErrorGuaranteed`. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 55201d17f714d..229e108d5d640 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -63,7 +63,7 @@ pub trait InferCtxtExt<'tcx> { errors: &[FulfillmentError<'tcx>], body_id: Option, fallback_has_occurred: bool, - ); + ) -> ErrorGuaranteed; fn report_overflow_error( &self, @@ -111,7 +111,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { errors: &[FulfillmentError<'tcx>], body_id: Option, fallback_has_occurred: bool, - ) { + ) -> ErrorGuaranteed { #[derive(Debug)] struct ErrorDescriptor<'tcx> { predicate: ty::Predicate<'tcx>, @@ -190,6 +190,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { self.report_fulfillment_error(error, body_id, fallback_has_occurred); } } + + self.tcx.sess.delay_span_bug(DUMMY_SP, "expected fullfillment errors") } /// Reports that an overflow has occurred and halts compilation. We @@ -312,7 +314,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let predicate_is_const = ty::BoundConstness::ConstIfConst == trait_predicate.skip_binder().constness; - if self.tcx.sess.has_errors() && trait_predicate.references_error() { + if self.tcx.sess.has_errors().is_some() + && trait_predicate.references_error() + { return; } let trait_ref = trait_predicate.to_poly_trait_ref(); @@ -919,7 +923,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } // Already reported in the query. - SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(ErrorGuaranteed)) => { + SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(_)) => { // FIXME(eddyb) remove this once `ErrorGuaranteed` becomes a proof token. self.tcx.sess.delay_span_bug(span, "`ErrorGuaranteed` without an error"); return; @@ -1857,7 +1861,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { // Same hacky approach as above to avoid deluging user // with error messages. if arg.references_error() - || self.tcx.sess.has_errors() + || self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() { return; @@ -1868,7 +1872,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { ty::PredicateKind::Subtype(data) => { if data.references_error() - || self.tcx.sess.has_errors() + || self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() { // no need to overload user in such cases @@ -1910,7 +1914,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { } _ => { - if self.tcx.sess.has_errors() || self.is_tainted_by_errors() { + if self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() { return; } let mut err = struct_span_err!( diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 62c6c8454797a..9ac8dc59a1d1e 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -3,7 +3,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::obligation_forest::ProcessResult; use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome}; use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor}; -use rustc_errors::ErrorGuaranteed; use rustc_infer::traits::ProjectionCacheKey; use rustc_infer::traits::{SelectionError, TraitEngine, TraitEngineExt as _, TraitObligation}; use rustc_middle::mir::interpret::ErrorHandled; @@ -630,14 +629,12 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { ), } } - (Err(ErrorHandled::Reported(ErrorGuaranteed)), _) - | (_, Err(ErrorHandled::Reported(ErrorGuaranteed))) => { - ProcessResult::Error(CodeSelectionError( - SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error( - ErrorGuaranteed, - )), - )) - } + (Err(ErrorHandled::Reported(reported)), _) + | (_, Err(ErrorHandled::Reported(reported))) => ProcessResult::Error( + CodeSelectionError(SelectionError::NotConstEvaluatable( + NotConstEvaluatable::Error(reported), + )), + ), (Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => { span_bug!( obligation.cause.span(self.selcx.tcx()), diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index bf94c61e6c2ce..a1efeb0b06b9b 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -231,8 +231,8 @@ fn do_normalize_predicates<'tcx>( match fully_normalize(&infcx, fulfill_cx, cause, elaborated_env, predicates) { Ok(predicates) => predicates, Err(errors) => { - infcx.report_fulfillment_errors(&errors, None, false); - return Err(ErrorGuaranteed); + let reported = infcx.report_fulfillment_errors(&errors, None, false); + return Err(reported); } }; @@ -258,13 +258,15 @@ fn do_normalize_predicates<'tcx>( // represents a legitimate failure due to some kind of // unconstrained variable, and it seems better not to ICE, // all things considered. - tcx.sess.span_err(span, &fixup_err.to_string()); - return Err(ErrorGuaranteed); + let reported = tcx.sess.span_err(span, &fixup_err.to_string()); + return Err(reported); } }; if predicates.needs_infer() { - tcx.sess.delay_span_bug(span, "encountered inference variables after `fully_resolve`"); - Err(ErrorGuaranteed) + let reported = tcx + .sess + .delay_span_bug(span, "encountered inference variables after `fully_resolve`"); + Err(reported) } else { Ok(predicates) } diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs index 2f697c1fa27b7..38be28c07ff18 100644 --- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs @@ -6,7 +6,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt}; use rustc_parse_format::{ParseMode, Parser, Piece, Position}; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; #[derive(Clone, Debug)] pub struct OnUnimplementedFormatString(Symbol); @@ -47,8 +47,7 @@ fn parse_error( if let Some(note) = note { diag.note(note); } - diag.emit(); - ErrorGuaranteed + diag.emit() } impl<'tcx> OnUnimplementedDirective { @@ -59,7 +58,7 @@ impl<'tcx> OnUnimplementedDirective { span: Span, is_root: bool, ) -> Result { - let mut errored = false; + let mut errored = None; let mut item_iter = items.iter(); let parse_value = |value_str| { @@ -91,8 +90,8 @@ impl<'tcx> OnUnimplementedDirective { ) })?; attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |item| { - if let Some(symbol) = item.value_str() && parse_value(symbol).is_err() { - errored = true; + if let Some(symbol) = item.value_str() && let Err(guar) = parse_value(symbol) { + errored = Some(guar); } true }); @@ -134,13 +133,10 @@ impl<'tcx> OnUnimplementedDirective { && note.is_none() { if let Some(items) = item.meta_item_list() { - if let Ok(subcommand) = - Self::parse(tcx, item_def_id, &items, item.span(), false) - { - subcommands.push(subcommand); - } else { - errored = true; - } + match Self::parse(tcx, item_def_id, &items, item.span(), false) { + Ok(subcommand) => subcommands.push(subcommand), + Err(reported) => errored = Some(reported), + }; continue; } } else if item.has_name(sym::append_const_msg) && append_const_msg.is_none() { @@ -163,8 +159,8 @@ impl<'tcx> OnUnimplementedDirective { ); } - if errored { - Err(ErrorGuaranteed) + if let Some(reported) = errored { + Err(reported) } else { Ok(OnUnimplementedDirective { condition, @@ -203,7 +199,9 @@ impl<'tcx> OnUnimplementedDirective { append_const_msg: None, })) } else { - return Err(ErrorGuaranteed); + let reported = + tcx.sess.delay_span_bug(DUMMY_SP, "of_item: neither meta_item_list nor value_str"); + return Err(reported); }; debug!("of_item({:?}) = {:?}", item_def_id, result); result @@ -327,7 +325,7 @@ impl<'tcx> OnUnimplementedFormatString { match generics.params.iter().find(|param| param.name == s) { Some(_) => (), None => { - struct_span_err!( + let reported = struct_span_err!( tcx.sess, span, E0230, @@ -340,20 +338,20 @@ impl<'tcx> OnUnimplementedFormatString { } ) .emit(); - result = Err(ErrorGuaranteed); + result = Err(reported); } } } // `{:1}` and `{}` are not to be used Position::ArgumentIs(_) | Position::ArgumentImplicitlyIs(_) => { - struct_span_err!( + let reported = struct_span_err!( tcx.sess, span, E0231, "only named substitution parameters are allowed" ) .emit(); - result = Err(ErrorGuaranteed); + result = Err(reported); } }, } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 11f0507d6fd61..614a5e0480997 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1396,7 +1396,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // `rustc_ty_utils::instance::resolve_associated_item()`. let node_item = assoc_def(selcx, impl_data.impl_def_id, obligation.predicate.item_def_id) - .map_err(|ErrorGuaranteed| ())?; + .map_err(|ErrorGuaranteed { .. }| ())?; if node_item.is_final() { // Non-specializable items are always projectable. diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 8af4606db8520..cf929ee3cc056 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -29,7 +29,7 @@ use crate::traits::project::ProjectionCacheKeyExt; use crate::traits::ProjectionCacheKey; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::{Diagnostic, ErrorGuaranteed}; +use rustc_errors::Diagnostic; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::LateBoundRegionConversionTime; @@ -674,8 +674,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Err(_) => Ok(EvaluatedToErr), } } - (Err(ErrorHandled::Reported(ErrorGuaranteed)), _) - | (_, Err(ErrorHandled::Reported(ErrorGuaranteed))) => Ok(EvaluatedToErr), + (Err(ErrorHandled::Reported(_)), _) + | (_, Err(ErrorHandled::Reported(_))) => Ok(EvaluatedToErr), (Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => { span_bug!( obligation.cause.span(self.tcx()), diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index a8a53c297d1a4..79471065ccc67 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -16,14 +16,14 @@ use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine}; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::struct_span_err; +use rustc_errors::{struct_span_err, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::lint::LintDiagnosticBuilder; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; -use rustc_span::DUMMY_SP; +use rustc_span::{Span, DUMMY_SP}; use super::util::impl_trait_ref_and_oblig; use super::{FulfillmentContext, SelectionContext}; @@ -377,8 +377,7 @@ fn report_negative_positive_conflict( } } - sg.has_errored = true; - err.emit(); + sg.has_errored = Some(err.emit()); } fn report_conflicting_impls( @@ -394,7 +393,13 @@ fn report_conflicting_impls( // Work to be done after we've built the DiagnosticBuilder. We have to define it // now because the struct_lint methods don't return back the DiagnosticBuilder // that's passed in. - let decorate = |err: LintDiagnosticBuilder<'_>| { + fn decorate( + tcx: TyCtxt<'_>, + overlap: OverlapError, + used_to_be_allowed: Option, + impl_span: Span, + err: LintDiagnosticBuilder<'_, G>, + ) -> G { let msg = format!( "conflicting implementations of trait `{}`{}{}", overlap.trait_desc, @@ -440,17 +445,25 @@ fn report_conflicting_impls( coherence::add_placeholder_note(&mut err); } err.emit() - }; + } match used_to_be_allowed { None => { - sg.has_errored = true; - if overlap.with_impl.is_local() || !tcx.orphan_check_crate(()).contains(&impl_def_id) { + let reported = if overlap.with_impl.is_local() + || !tcx.orphan_check_crate(()).contains(&impl_def_id) + { let err = struct_span_err!(tcx.sess, impl_span, E0119, ""); - decorate(LintDiagnosticBuilder::new(err.forget_guarantee())); + Some(decorate( + tcx, + overlap, + used_to_be_allowed, + impl_span, + LintDiagnosticBuilder::new(err), + )) } else { - tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"); - } + Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check")) + }; + sg.has_errored = reported; } Some(kind) => { let lint = match kind { @@ -461,8 +474,10 @@ fn report_conflicting_impls( lint, tcx.hir().local_def_id_to_hir_id(impl_def_id), impl_span, - decorate, - ) + |ldb| { + decorate(tcx, overlap, used_to_be_allowed, impl_span, ldb); + }, + ); } }; } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 41467ce2f622f..295a91959eb19 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -306,9 +306,9 @@ fn resolve_associated_item<'tcx>( resolved_ty, ); let span = tcx.def_span(leaf_def.item.def_id); - tcx.sess.delay_span_bug(span, &msg); + let reported = tcx.sess.delay_span_bug(span, &msg); - return Err(ErrorGuaranteed); + return Err(reported); } } diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs index 7e9abe3a250db..5f01559226c77 100644 --- a/compiler/rustc_typeck/src/astconv/errors.rs +++ b/compiler/rustc_typeck/src/astconv/errors.rs @@ -1,6 +1,6 @@ use crate::astconv::AstConv; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{pluralize, struct_span_err, Applicability}; +use rustc_errors::{pluralize, struct_span_err, Applicability, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty; @@ -195,7 +195,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ty_param_name: &str, assoc_name: Ident, span: Span, - ) where + ) -> ErrorGuaranteed + where I: Iterator>, { // The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a @@ -231,7 +232,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_label(span, format!("associated type `{}` not found", assoc_name)); } - err.emit(); + err.emit() } /// When there are any missing associated types, emit an E0191 error and attempt to supply a diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index e8b64587eeea6..d56c521d23d32 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -6,7 +6,7 @@ use crate::astconv::{ use crate::errors::AssocTypeBindingNotAllowed; use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs}; use rustc_ast::ast::ParamKindOrd; -use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed}; +use rustc_errors::{struct_span_err, Applicability, Diagnostic}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; @@ -456,51 +456,55 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut invalid_args = vec![]; - let mut check_lifetime_args = |min_expected_args: usize, - max_expected_args: usize, - provided_args: usize, - late_bounds_ignore: bool| - -> bool { - if (min_expected_args..=max_expected_args).contains(&provided_args) { - return true; - } + let mut check_lifetime_args = + |min_expected_args: usize, + max_expected_args: usize, + provided_args: usize, + late_bounds_ignore: bool| { + if (min_expected_args..=max_expected_args).contains(&provided_args) { + return Ok(()); + } - if late_bounds_ignore { - return true; - } + if late_bounds_ignore { + return Ok(()); + } - if provided_args > max_expected_args { - invalid_args.extend( - gen_args.args[max_expected_args..provided_args].iter().map(|arg| arg.span()), - ); - }; + if provided_args > max_expected_args { + invalid_args.extend( + gen_args.args[max_expected_args..provided_args] + .iter() + .map(|arg| arg.span()), + ); + }; - let gen_args_info = if provided_args > min_expected_args { - invalid_args.extend( - gen_args.args[min_expected_args..provided_args].iter().map(|arg| arg.span()), - ); - let num_redundant_args = provided_args - min_expected_args; - GenericArgsInfo::ExcessLifetimes { num_redundant_args } - } else { - let num_missing_args = min_expected_args - provided_args; - GenericArgsInfo::MissingLifetimes { num_missing_args } + let gen_args_info = if provided_args > min_expected_args { + invalid_args.extend( + gen_args.args[min_expected_args..provided_args] + .iter() + .map(|arg| arg.span()), + ); + let num_redundant_args = provided_args - min_expected_args; + GenericArgsInfo::ExcessLifetimes { num_redundant_args } + } else { + let num_missing_args = min_expected_args - provided_args; + GenericArgsInfo::MissingLifetimes { num_missing_args } + }; + + let reported = WrongNumberOfGenericArgs::new( + tcx, + gen_args_info, + seg, + gen_params, + has_self as usize, + gen_args, + def_id, + ) + .diagnostic() + .emit(); + + Err(reported) }; - WrongNumberOfGenericArgs::new( - tcx, - gen_args_info, - seg, - gen_params, - has_self as usize, - gen_args, - def_id, - ) - .diagnostic() - .emit(); - - false - }; - let min_expected_lifetime_args = if infer_lifetimes { 0 } else { param_counts.lifetimes }; let max_expected_lifetime_args = param_counts.lifetimes; let num_provided_lifetime_args = gen_args.num_lifetime_params(); @@ -527,7 +531,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "check_types_and_consts" ); if (expected_min..=expected_max).contains(&provided) { - return true; + return Ok(()); } let num_default_params = expected_max - expected_min; @@ -561,7 +565,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!(?gen_args_info); - WrongNumberOfGenericArgs::new( + let reported = WrongNumberOfGenericArgs::new( tcx, gen_args_info, seg, @@ -573,7 +577,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .diagnostic() .emit_unless(gen_args.has_err()); - false + Err(reported) }; let args_correct = { @@ -599,11 +603,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { GenericArgCountResult { explicit_late_bound, - correct: if lifetimes_correct && args_correct { - Ok(()) - } else { - Err(GenericArgCountMismatch { reported: Some(ErrorGuaranteed), invalid_args }) - }, + correct: lifetimes_correct.and(args_correct).map_err(|reported| { + GenericArgCountMismatch { reported: Some(reported), invalid_args } + }), } } @@ -700,7 +702,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { LATE_BOUND_LIFETIME_ARGUMENTS, args.args[0].id(), multispan, - |lint| lint.build(msg).emit(), + |lint| { + lint.build(msg).emit(); + }, ); } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 144953caa4c3b..b04d304d2ca15 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1570,7 +1570,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { type_str: &str, trait_str: &str, name: Symbol, - ) { + ) -> ErrorGuaranteed { let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type"); if let (true, Ok(snippet)) = ( self.tcx() @@ -1594,7 +1594,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { Applicability::HasPlaceholders, ); } - err.emit(); + err.emit() } // Search for a bound on a type parameter which includes the associated item @@ -1661,13 +1661,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { (Some(bound), _) => (bound, matching_candidates.next()), (None, Some(bound)) => (bound, const_candidates.next()), (None, None) => { - self.complain_about_assoc_type_not_found( + let reported = self.complain_about_assoc_type_not_found( all_candidates, &ty_param_name(), assoc_name, span, ); - return Err(ErrorGuaranteed); + return Err(reported); } }; debug!("one_bound_for_assoc_type: bound = {:?}", bound); @@ -1752,9 +1752,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { where_bounds.join(",\n"), )); } - err.emit(); + let reported = err.emit(); if !where_bounds.is_empty() { - return Err(ErrorGuaranteed); + return Err(reported); } } @@ -1811,7 +1811,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // trait reference. let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else { // A cycle error occurred, most likely. - return Err(ErrorGuaranteed); + let guar = tcx.sess.delay_span_bug(span, "expected cycle error"); + return Err(guar); }; self.one_bound_for_assoc_type( @@ -1828,10 +1829,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { | Res::Def(DefKind::TyParam, param_did), ) => self.find_bound_for_assoc_item(param_did.expect_local(), assoc_ident, span)?, _ => { - if variant_resolution.is_some() { + let reported = if variant_resolution.is_some() { // Variant in type position let msg = format!("expected type, found variant `{}`", assoc_ident); - tcx.sess.span_err(span, &msg); + tcx.sess.span_err(span, &msg) } else if qself_ty.is_enum() { let mut err = struct_span_err!( tcx.sess, @@ -1870,17 +1871,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_label(sp, format!("variant `{}` not found here", assoc_ident)); } - err.emit(); - } else if !qself_ty.references_error() { + err.emit() + } else if let Some(reported) = qself_ty.error_reported() { + reported + } else { // Don't print `TyErr` to the user. self.report_ambiguous_associated_type( span, &qself_ty.to_string(), "Trait", assoc_ident.name, - ); - } - return Err(ErrorGuaranteed); + ) + }; + return Err(reported); } }; @@ -1898,8 +1901,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // but it was used in a type position. let Some(item) = item else { let msg = format!("found associated const `{assoc_ident}` when type was expected"); - tcx.sess.struct_span_err(span, &msg).emit(); - return Err(ErrorGuaranteed); + let guar = tcx.sess.struct_span_err(span, &msg).emit(); + return Err(guar); }; let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, assoc_segment, bound); @@ -2737,7 +2740,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { sugg, Applicability::MachineApplicable, ) - .emit() + .emit(); }, ); } diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs index d3e9820834ab9..7ce428ea12466 100644 --- a/compiler/rustc_typeck/src/check/cast.rs +++ b/compiler/rustc_typeck/src/check/cast.rs @@ -91,8 +91,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let t = self.resolve_vars_if_possible(t); - if t.references_error() { - return Err(ErrorGuaranteed); + if let Some(reported) = t.error_reported() { + return Err(reported); } if self.type_is_known_to_be_sized_modulo_regions(t, span) { @@ -139,10 +139,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Adt(..) | ty::Never | ty::Error(_) => { - self.tcx + let reported = self + .tcx .sess .delay_span_bug(span, &format!("`{:?}` should be sized but is not?", t)); - return Err(ErrorGuaranteed); + return Err(reported); } }) } @@ -174,7 +175,7 @@ pub enum CastError { } impl From for CastError { - fn from(ErrorGuaranteed: ErrorGuaranteed) -> Self { + fn from(_: ErrorGuaranteed) -> Self { CastError::ErrorGuaranteed } } @@ -213,8 +214,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { // inference is more completely known. match cast_ty.kind() { ty::Dynamic(..) | ty::Slice(..) => { - check.report_cast_to_unsized_type(fcx); - Err(ErrorGuaranteed) + let reported = check.report_cast_to_unsized_type(fcx); + Err(reported) } _ => Ok(check), } @@ -588,9 +589,11 @@ impl<'a, 'tcx> CastCheck<'tcx> { } } - fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'tcx>) { - if self.cast_ty.references_error() || self.expr_ty.references_error() { - return; + fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'tcx>) -> ErrorGuaranteed { + if let Some(reported) = + self.cast_ty.error_reported().or_else(|| self.expr_ty.error_reported()) + { + return reported; } let tstr = fcx.ty_to_string(self.cast_ty); @@ -651,7 +654,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { err.span_help(self.expr.span, "consider using a box or reference as appropriate"); } } - err.emit(); + err.emit() } fn trivial_cast_lint(&self, fcx: &FnCtxt<'a, 'tcx>) { diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 9016a8ffe9add..e57d55fdc2377 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -49,7 +49,7 @@ pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab } None => { tcx.struct_span_lint_hir(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| { - lint.build("use of calling convention not supported on this target").emit() + lint.build("use of calling convention not supported on this target").emit(); }); } } @@ -136,7 +136,7 @@ pub(super) fn check_fn<'a, 'tcx>( }; if let Some(header) = item { - tcx.sess.span_err(header.span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple") + tcx.sess.span_err(header.span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple"); } }; @@ -625,11 +625,11 @@ pub(super) fn check_opaque_for_cycles<'tcx>( origin: &hir::OpaqueTyOrigin, ) -> Result<(), ErrorGuaranteed> { if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() { - match origin { + let reported = match origin { hir::OpaqueTyOrigin::AsyncFn(..) => async_opaque_type_cycle_error(tcx, span), _ => opaque_type_cycle_error(tcx, def_id, span), - } - Err(ErrorGuaranteed) + }; + Err(reported) } else { Ok(()) } @@ -680,13 +680,15 @@ fn check_opaque_meets_bounds<'tcx>( trace!(?hidden_type); match infcx.at(&misc_cause, param_env).eq(opaque_defn.concrete_ty, hidden_type) { Ok(infer_ok) => inh.register_infer_ok_obligations(infer_ok), - Err(ty_err) => tcx.sess.delay_span_bug( - span, - &format!( - "could not check bounds on revealed type `{}`:\n{}", - hidden_type, ty_err, - ), - ), + Err(ty_err) => { + tcx.sess.delay_span_bug( + span, + &format!( + "could not check bounds on revealed type `{}`:\n{}", + hidden_type, ty_err, + ), + ); + } } } @@ -1422,7 +1424,7 @@ pub(super) fn check_type_params_are_used<'tcx>( if ty.references_error() { // If there is already another error, do not emit // an error for not using a type parameter. - assert!(tcx.sess.has_errors()); + assert!(tcx.sess.has_errors().is_some()); return; } @@ -1463,14 +1465,14 @@ pub(super) use wfcheck::check_trait_item as check_trait_item_well_formed; pub(super) use wfcheck::check_impl_item as check_impl_item_well_formed; -fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) { +fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) -> ErrorGuaranteed { struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing") .span_label(span, "recursive `async fn`") .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`") .note( "consider using the `async_recursion` crate: https://crates.io/crates/async_recursion", ) - .emit(); + .emit() } /// Emit an error for recursive opaque types. @@ -1481,7 +1483,7 @@ fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) { /// /// If all the return expressions evaluate to `!`, then we explain that the error will go away /// after changing it. This can happen when a user uses `panic!()` or similar as a placeholder. -fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) { +fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> ErrorGuaranteed { let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type"); let mut label = false; @@ -1550,5 +1552,5 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) { if !label { err.span_label(span, "cannot resolve opaque type"); } - err.emit(); + err.emit() } diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index d4a473adaf010..f5477f7103cb3 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -41,35 +41,30 @@ crate fn compare_impl_method<'tcx>( let impl_m_span = tcx.sess.source_map().guess_head_span(impl_m_span); - if let Err(ErrorGuaranteed) = - compare_self_type(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref) - { + if let Err(_) = compare_self_type(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref) { return; } - if let Err(ErrorGuaranteed) = - compare_number_of_generics(tcx, impl_m, impl_m_span, trait_m, trait_item_span) - { + if let Err(_) = compare_number_of_generics(tcx, impl_m, impl_m_span, trait_m, trait_item_span) { return; } - if let Err(ErrorGuaranteed) = + if let Err(_) = compare_number_of_method_arguments(tcx, impl_m, impl_m_span, trait_m, trait_item_span) { return; } - if let Err(ErrorGuaranteed) = compare_synthetic_generics(tcx, impl_m, trait_m) { + if let Err(_) = compare_synthetic_generics(tcx, impl_m, trait_m) { return; } - if let Err(ErrorGuaranteed) = - compare_predicate_entailment(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref) + if let Err(_) = compare_predicate_entailment(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref) { return; } - if let Err(ErrorGuaranteed) = compare_const_param_types(tcx, impl_m, trait_m, trait_item_span) { + if let Err(_) = compare_const_param_types(tcx, impl_m, trait_m, trait_item_span) { return; } } @@ -385,16 +380,16 @@ fn compare_predicate_entailment<'tcx>( &terr, false, ); - diag.emit(); - return Err(ErrorGuaranteed); + + return Err(diag.emit()); } // Check that all obligations are satisfied by the implementation's // version. let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx); if !errors.is_empty() { - infcx.report_fulfillment_errors(&errors, None, false); - return Err(ErrorGuaranteed); + let reported = infcx.report_fulfillment_errors(&errors, None, false); + return Err(reported); } // Finally, resolve all regions. This catches wily misuses of @@ -450,13 +445,13 @@ fn check_region_bounds_on_impl_item<'tcx>( .map_or(def_sp, |g| g.span) }); - tcx.sess.emit_err(LifetimesOrBoundsMismatchOnTrait { + let reported = tcx.sess.emit_err(LifetimesOrBoundsMismatchOnTrait { span, item_kind, ident: impl_m.ident(tcx), generics_span, }); - return Err(ErrorGuaranteed); + return Err(reported); } Ok(()) @@ -550,8 +545,8 @@ fn compare_self_type<'tcx>( } else { err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx)); } - err.emit(); - return Err(ErrorGuaranteed); + let reported = err.emit(); + return Err(reported); } (true, false) => { @@ -570,8 +565,8 @@ fn compare_self_type<'tcx>( } else { err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx)); } - err.emit(); - return Err(ErrorGuaranteed); + let reported = err.emit(); + return Err(reported); } } @@ -595,11 +590,9 @@ fn compare_number_of_generics<'tcx>( let item_kind = assoc_item_kind_str(impl_); - let mut err_occurred = false; + let mut err_occurred = None; for (kind, trait_count, impl_count) in matchings { if impl_count != trait_count { - err_occurred = true; - let (trait_spans, impl_trait_spans) = if let Some(def_id) = trait_.def_id.as_local() { let trait_item = tcx.hir().expect_trait_item(def_id); if trait_item.generics.params.is_empty() { @@ -690,11 +683,12 @@ fn compare_number_of_generics<'tcx>( err.span_label(*span, "`impl Trait` introduces an implicit type parameter"); } - err.emit(); + let reported = err.emit(); + err_occurred = Some(reported); } } - if err_occurred { Err(ErrorGuaranteed) } else { Ok(()) } + if let Some(reported) = err_occurred { Err(reported) } else { Ok(()) } } fn compare_number_of_method_arguments<'tcx>( @@ -772,8 +766,8 @@ fn compare_number_of_method_arguments<'tcx>( impl_number_args ), ); - err.emit(); - return Err(ErrorGuaranteed); + let reported = err.emit(); + return Err(reported); } Ok(()) @@ -789,7 +783,7 @@ fn compare_synthetic_generics<'tcx>( // 2. Explanation as to what is going on // If we get here, we already have the same number of generics, so the zip will // be okay. - let mut error_found = false; + let mut error_found = None; let impl_m_generics = tcx.generics_of(impl_m.def_id); let trait_m_generics = tcx.generics_of(trait_m.def_id); let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| match param.kind { @@ -918,11 +912,11 @@ fn compare_synthetic_generics<'tcx>( } _ => unreachable!(), } - err.emit(); - error_found = true; + let reported = err.emit(); + error_found = Some(reported); } } - if error_found { Err(ErrorGuaranteed) } else { Ok(()) } + if let Some(reported) = error_found { Err(reported) } else { Ok(()) } } fn compare_const_param_types<'tcx>( @@ -979,8 +973,8 @@ fn compare_const_param_types<'tcx>( trait_ty ), ); - err.emit(); - return Err(ErrorGuaranteed); + let reported = err.emit(); + return Err(reported); } } @@ -1203,8 +1197,8 @@ fn compare_type_predicate_entailment<'tcx>( // version. let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx); if !errors.is_empty() { - infcx.report_fulfillment_errors(&errors, None, false); - return Err(ErrorGuaranteed); + let reported = infcx.report_fulfillment_errors(&errors, None, false); + return Err(reported); } // Finally, resolve all regions. This catches wily misuses of @@ -1427,8 +1421,8 @@ pub fn check_type_bounds<'tcx>( // version. let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx); if !errors.is_empty() { - infcx.report_fulfillment_errors(&errors, None, false); - return Err(ErrorGuaranteed); + let reported = infcx.report_fulfillment_errors(&errors, None, false); + return Err(reported); } // Finally, resolve all regions. This catches wily misuses of diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs index 1849ece9f76d9..d38777bea5990 100644 --- a/compiler/rustc_typeck/src/check/dropck.rs +++ b/compiler/rustc_typeck/src/check/dropck.rs @@ -55,11 +55,11 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro // already checked by coherence, but compilation may // not have been terminated. let span = tcx.def_span(drop_impl_did); - tcx.sess.delay_span_bug( + let reported = tcx.sess.delay_span_bug( span, &format!("should have been rejected by coherence check: {}", dtor_self_type), ); - Err(ErrorGuaranteed) + Err(reported) } } } @@ -94,7 +94,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( Err(_) => { let item_span = tcx.def_span(self_type_did); let self_descr = tcx.def_kind(self_type_did).descr(self_type_did); - struct_span_err!( + let reported = struct_span_err!( tcx.sess, drop_impl_span, E0366, @@ -109,15 +109,15 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( ), ) .emit(); - return Err(ErrorGuaranteed); + return Err(reported); } } let errors = fulfillment_cx.select_all_or_error(&infcx); if !errors.is_empty() { // this could be reached when we get lazy normalization - infcx.report_fulfillment_errors(&errors, None, false); - return Err(ErrorGuaranteed); + let reported = infcx.report_fulfillment_errors(&errors, None, false); + return Err(reported); } // NB. It seems a bit... suspicious to use an empty param-env @@ -258,7 +258,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( if !assumptions_in_impl_context.iter().copied().any(predicate_matches_closure) { let item_span = tcx.def_span(self_type_did); let self_descr = tcx.def_kind(self_type_did).descr(self_type_did.to_def_id()); - struct_span_err!( + let reported = struct_span_err!( tcx.sess, predicate_sp, E0367, @@ -268,7 +268,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( ) .span_note(item_span, "the implementor must specify the same requirement") .emit(); - result = Err(ErrorGuaranteed); + result = Err(reported); } } diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index d944bb7624177..0a720f1502503 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -667,7 +667,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // else an error would have been flagged by the // `loops` pass for using break with an expression // where you are not supposed to. - assert!(expr_opt.is_none() || self.tcx.sess.has_errors()); + assert!(expr_opt.is_none() || self.tcx.sess.has_errors().is_some()); } // If we encountered a `break`, then (no surprise) it may be possible to break from the @@ -1187,7 +1187,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { deferred_cast_checks.push(cast_check); t_cast } - Err(ErrorGuaranteed) => self.tcx.ty_error(), + Err(_) => self.tcx.ty_error(), } } } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index ed70b85e3f147..e3439a6f1d963 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -315,16 +315,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // FIXME: currently we never try to compose autoderefs // and ReifyFnPointer/UnsafeFnPointer, but we could. - _ => self.tcx.sess.delay_span_bug( - expr.span, - &format!( - "while adjusting {:?}, can't compose {:?} and {:?}", - expr, - entry.get(), - adj - ), - ), - }; + _ => { + self.tcx.sess.delay_span_bug( + expr.span, + &format!( + "while adjusting {:?}, can't compose {:?} and {:?}", + expr, + entry.get(), + adj + ), + ); + } + } *entry.get_mut() = adj; } } @@ -903,7 +905,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .or_else(|error| { let result = match error { method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)), - _ => Err(ErrorGuaranteed), + _ => Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()), }; // If we have a path like `MyTrait::missing_method`, then don't register diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index e79085fdad28d..4e1645adca5d3 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -412,7 +412,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint::builtin::TYVAR_BEHIND_RAW_POINTER, scope_expr_id, span, - |lint| lint.build("type annotations needed").emit(), + |lint| { + lint.build("type annotations needed").emit(); + }, ); } } else { diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index 62f7c382bc90c..16ffabb76a515 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -81,7 +81,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.is_tainted_by_errors() { // FIXME(eddyb) keep track of `ErrorGuaranteed` from where the error was emitted. - wbcx.typeck_results.tainted_by_errors = Some(ErrorGuaranteed); + wbcx.typeck_results.tainted_by_errors = + Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); } debug!("writeback: typeck results for {:?} are {:#?}", item_def_id, wbcx.typeck_results); @@ -662,7 +663,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // users of the typeck results don't produce extra errors, or worse, ICEs. if resolver.replaced_with_error { // FIXME(eddyb) keep track of `ErrorGuaranteed` from where the error was emitted. - self.typeck_results.tainted_by_errors = Some(ErrorGuaranteed); + self.typeck_results.tainted_by_errors = + Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); } x @@ -707,7 +709,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { } fn report_type_error(&self, t: Ty<'tcx>) { - if !self.tcx.sess.has_errors() { + if !self.tcx.sess.has_errors().is_some() { self.infcx .emit_inference_failure_err( Some(self.body.id()), @@ -721,7 +723,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { } fn report_const_error(&self, c: ty::Const<'tcx>) { - if !self.tcx.sess.has_errors() { + if self.tcx.sess.has_errors().is_none() { self.infcx .emit_inference_failure_err( Some(self.body.id()), diff --git a/compiler/rustc_typeck/src/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs index 5dfd444133a37..4b23cc4db85ba 100644 --- a/compiler/rustc_typeck/src/coherence/orphan.rs +++ b/compiler/rustc_typeck/src/coherence/orphan.rs @@ -21,7 +21,7 @@ pub(super) fn orphan_check_crate(tcx: TyCtxt<'_>, (): ()) -> &[LocalDefId] { for &impl_of_trait in impls_of_trait { match orphan_check_impl(tcx, impl_of_trait) { Ok(()) => {} - Err(ErrorGuaranteed) => errors.push(impl_of_trait), + Err(_) => errors.push(impl_of_trait), } } @@ -135,17 +135,19 @@ fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua }; if let Some((msg, label)) = msg { - struct_span_err!(tcx.sess, sp, E0321, "{}", msg).span_label(sp, label).emit(); - return Err(ErrorGuaranteed); + let reported = + struct_span_err!(tcx.sess, sp, E0321, "{}", msg).span_label(sp, label).emit(); + return Err(reported); } } if let ty::Opaque(def_id, _) = *trait_ref.self_ty().kind() { - tcx.sess + let reported = tcx + .sess .struct_span_err(sp, "cannot implement trait on type alias impl trait") .span_note(tcx.def_span(def_id), "type alias impl trait defined here") .emit(); - return Err(ErrorGuaranteed); + return Err(reported); } Ok(()) diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 3247a292242a3..d422f355ad3a4 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -1,4 +1,4 @@ -use rustc_errors::{Applicability, ErrorGuaranteed, StashKey}; +use rustc_errors::{Applicability, StashKey}; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -366,7 +366,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { owner, def_id, ), ); - if let Some(ErrorGuaranteed) = + if let Some(_) = tcx.typeck(owner).tainted_by_errors { // Some error in the diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index be4958ea06276..cb59438e3432f 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -523,7 +523,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // struct; however, when EUV is run during typeck, it // may not. This will generate an error earlier in typeck, // so we can just ignore it. - if !self.tcx().sess.has_errors() { + if !self.tcx().sess.has_errors().is_some() { span_bug!(with_expr.span, "with expression doesn't evaluate to a struct"); } } diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index d665b6d068e06..5d4dfd3caefcc 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -537,7 +537,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { check_unused::check_crate(tcx); check_for_entry_fn(tcx); - if tcx.sess.err_count() == 0 { Ok(()) } else { Err(ErrorGuaranteed) } + if let Some(reported) = tcx.sess.has_errors() { Err(reported) } else { Ok(()) } } /// A quasi-deprecated helper used in rustdoc and clippy to get diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c0e7cd0b1f580..42b7eec5d3aa9 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -834,7 +834,9 @@ impl AttributesExt for [ast::Attribute] { { match Cfg::parse(cfg_mi) { Ok(new_cfg) => cfg &= new_cfg, - Err(e) => sess.span_err(e.span, e.msg), + Err(e) => { + sess.span_err(e.span, e.msg); + } } } } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 2b82575f71083..bd64e2b03ce0c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -452,7 +452,7 @@ crate fn run_global_ctxt( } } - if tcx.sess.diagnostic().has_errors_or_lint_errors() { + if tcx.sess.diagnostic().has_errors_or_lint_errors().is_some() { rustc_errors::FatalError.raise(); } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 728b7720f739d..8db5f8b0cff8b 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -149,7 +149,7 @@ crate fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> { collector }); - if compiler.session().diagnostic().has_errors_or_lint_errors() { + if compiler.session().diagnostic().has_errors_or_lint_errors().is_some() { FatalError.raise(); } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index f378915172a69..f59222b780d3e 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -179,7 +179,7 @@ pub fn main() { let exit_code = rustc_driver::catch_with_exit_code(|| match get_args() { Some(args) => main_args(&args), - _ => Err(ErrorGuaranteed), + _ => Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()), }); process::exit(exit_code); } @@ -692,7 +692,13 @@ fn main_args(at_args: &[String]) -> MainResult { // codes from `from_matches` here. let options = match config::Options::from_matches(&matches) { Ok(opts) => opts, - Err(code) => return if code == 0 { Ok(()) } else { Err(ErrorGuaranteed) }, + Err(code) => { + return if code == 0 { + Ok(()) + } else { + Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()) + }; + } }; rustc_interface::util::run_in_thread_pool_with_globals( options.edition, @@ -705,8 +711,8 @@ fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainRes match res { Ok(()) => Ok(()), Err(err) => { - diag.struct_err(&err).emit(); - Err(ErrorGuaranteed) + let reported = diag.struct_err(&err).emit(); + Err(reported) } } } @@ -790,7 +796,7 @@ fn main_options(options: config::Options) -> MainResult { (resolver.clone(), resolver_caches) }; - if sess.diagnostic().has_errors_or_lint_errors() { + if sess.diagnostic().has_errors_or_lint_errors().is_some() { sess.fatal("Compilation failed, aborting rustdoc"); } diff --git a/src/librustdoc/passes/bare_urls.rs b/src/librustdoc/passes/bare_urls.rs index 71fa71750f43a..81f371840ae46 100644 --- a/src/librustdoc/passes/bare_urls.rs +++ b/src/librustdoc/passes/bare_urls.rs @@ -80,7 +80,7 @@ impl<'a, 'tcx> DocVisitor for BareUrlsLinter<'a, 'tcx> { format!("<{}>", url), Applicability::MachineApplicable, ) - .emit() + .emit(); }); }; diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index c4aa31ad91230..8d9b3377a6986 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -91,7 +91,7 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { // lambda that will use the lint to start a new diagnostic and add // a suggestion to it when needed. - let diag_builder = |lint: LintDiagnosticBuilder<'_>| { + let diag_builder = |lint: LintDiagnosticBuilder<'_, ()>| { let explanation = if is_ignore { "`ignore` code blocks require valid Rust code for syntax highlighting; \ mark blocks that do not contain Rust code as text" diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index f1bb766f467af..2b17e3457d293 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -125,7 +125,9 @@ crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { crate::lint::MISSING_DOC_CODE_EXAMPLES, hir_id, sp, - |lint| lint.build("missing code example in this documentation").emit(), + |lint| { + lint.build("missing code example in this documentation").emit(); + }, ); } } else if tests.found_tests > 0 @@ -135,7 +137,9 @@ crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { crate::lint::PRIVATE_DOC_TESTS, hir_id, item.attr_span(cx.tcx), - |lint| lint.build("documentation test in private item").emit(), + |lint| { + lint.build("documentation test in private item").emit(); + }, ); } } diff --git a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs index ee668501ae78b..802b867a301aa 100644 --- a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs +++ b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs @@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingAllowedAttrPass { let allowed = |attr| pprust::attribute_to_string(attr).contains("allowed_attr"); if !cx.tcx.hir().attrs(item.hir_id()).iter().any(allowed) { cx.lint(MISSING_ALLOWED_ATTR, |lint| { - lint.build("Missing 'allowed_attr' attribute").set_span(span).emit() + lint.build("Missing 'allowed_attr' attribute").set_span(span).emit(); }); } } diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs index e726f8402ef9d..bc153faa8925a 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs @@ -34,7 +34,7 @@ macro_rules! fake_lint_pass { if !cx.sess().contains_name(attrs, $attr) { cx.lint(CRATE_NOT_OKAY, |lint| { let msg = format!("crate is not marked with #![{}]", $attr); - lint.build(&msg).set_span(span).emit() + lint.build(&msg).set_span(span).emit(); }); } )* diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index 4bbed5029802d..29d0abfbe5388 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -30,7 +30,7 @@ impl<'tcx> LateLintPass<'tcx> for Pass { let span = cx.tcx.def_span(CRATE_DEF_ID); if !cx.sess().contains_name(attrs, Symbol::intern("crate_okay")) { cx.lint(CRATE_NOT_OKAY, |lint| { - lint.build("crate is not marked with #![crate_okay]").set_span(span).emit() + lint.build("crate is not marked with #![crate_okay]").set_span(span).emit(); }); } } diff --git a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs index 98ba8b1225656..691cfb97d9218 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs @@ -23,10 +23,10 @@ impl<'tcx> LateLintPass<'tcx> for Pass { fn check_item(&mut self, cx: &LateContext, it: &rustc_hir::Item) { match it.ident.as_str() { "lintme" => cx.lint(TEST_LINT, |lint| { - lint.build("item is named 'lintme'").set_span(it.span).emit() + lint.build("item is named 'lintme'").set_span(it.span).emit(); }), "pleaselintme" => cx.lint(PLEASE_LINT, |lint| { - lint.build("item is named 'pleaselintme'").set_span(it.span).emit() + lint.build("item is named 'pleaselintme'").set_span(it.span).emit(); }), _ => {} } diff --git a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs index 42368ec36a028..285754928c219 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs @@ -22,7 +22,7 @@ impl EarlyLintPass for Pass { fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) { if it.ident.name.as_str() == "lintme" { cx.lint(TEST_LINT, |lint| { - lint.build("item is named 'lintme'").set_span(it.span).emit() + lint.build("item is named 'lintme'").set_span(it.span).emit(); }); } } diff --git a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs index 81feddf571323..3d5dba42b5f03 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs @@ -32,12 +32,12 @@ impl EarlyLintPass for Pass { fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) { if it.ident.name.as_str() == "lintme" { cx.lint(TEST_LINT, |lint| { - lint.build("item is named 'lintme'").set_span(it.span).emit() + lint.build("item is named 'lintme'").set_span(it.span).emit(); }); } if it.ident.name.as_str() == "lintmetoo" { cx.lint(TEST_GROUP, |lint| { - lint.build("item is named 'lintmetoo'").set_span(it.span).emit() + lint.build("item is named 'lintmetoo'").set_span(it.span).emit(); }); } } diff --git a/src/tools/rustfmt/src/parse/macros/lazy_static.rs b/src/tools/rustfmt/src/parse/macros/lazy_static.rs index 4c541de04be08..a8c2feec453c8 100644 --- a/src/tools/rustfmt/src/parse/macros/lazy_static.rs +++ b/src/tools/rustfmt/src/parse/macros/lazy_static.rs @@ -16,7 +16,7 @@ pub(crate) fn parse_lazy_static( ($method:ident $(,)* $($arg:expr),* $(,)*) => { match parser.$method($($arg,)*) { Ok(val) => { - if parser.sess.span_diagnostic.has_errors() { + if parser.sess.span_diagnostic.has_errors().is_some() { parser.sess.span_diagnostic.reset_err_count(); return None; } else { diff --git a/src/tools/rustfmt/src/parse/macros/mod.rs b/src/tools/rustfmt/src/parse/macros/mod.rs index fd738908170f8..3728f3a19b44f 100644 --- a/src/tools/rustfmt/src/parse/macros/mod.rs +++ b/src/tools/rustfmt/src/parse/macros/mod.rs @@ -28,7 +28,7 @@ fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { let mut cloned_parser = (*parser).clone(); match $parser(&mut cloned_parser) { Ok(x) => { - if parser.sess.span_diagnostic.has_errors() { + if parser.sess.span_diagnostic.has_errors().is_some() { parser.sess.span_diagnostic.reset_err_count(); } else { // Parsing succeeded. diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index 40a6d708d8ccc..a34ceed3fc91f 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -235,7 +235,7 @@ impl ParseSess { } pub(super) fn has_errors(&self) -> bool { - self.parse_sess.span_diagnostic.has_errors() + self.parse_sess.span_diagnostic.has_errors().is_some() } pub(super) fn reset_errors(&self) {