From b7e95dee65c35db8f8e07046d445b12d92cbae12 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 27 Jan 2022 09:44:25 +0000 Subject: [PATCH] rustc_errors: let `DiagnosticBuilder::emit` return a "guarantee of emission". --- .../rustc_borrowck/src/borrowck_errors.rs | 64 +++-- .../src/diagnostics/bound_region_errors.rs | 36 ++- .../src/diagnostics/conflict_errors.rs | 18 +- .../src/diagnostics/move_errors.rs | 6 +- .../src/diagnostics/outlives_suggestion.rs | 2 +- .../src/diagnostics/region_errors.rs | 14 +- compiler/rustc_borrowck/src/lib.rs | 24 +- compiler/rustc_borrowck/src/nll.rs | 2 +- compiler/rustc_builtin_macros/src/asm.rs | 15 +- compiler/rustc_builtin_macros/src/assert.rs | 8 +- compiler/rustc_builtin_macros/src/cfg.rs | 8 +- compiler/rustc_builtin_macros/src/format.rs | 4 +- .../rustc_builtin_macros/src/test_harness.rs | 8 +- compiler/rustc_codegen_ssa/src/back/write.rs | 2 +- .../rustc_const_eval/src/const_eval/error.rs | 40 +-- .../src/const_eval/eval_queries.rs | 3 +- .../src/transform/check_consts/ops.rs | 164 +++++++++--- .../rustc_errors/src/diagnostic_builder.rs | 234 +++++++++++++----- compiler/rustc_errors/src/lib.rs | 56 +++-- compiler/rustc_expand/src/base.rs | 20 +- compiler/rustc_expand/src/mbe/macro_rules.rs | 2 +- compiler/rustc_expand/src/module.rs | 6 +- .../rustc_expand/src/proc_macro_server.rs | 4 +- .../src/infer/error_reporting/mod.rs | 10 +- .../infer/error_reporting/need_type_info.rs | 8 +- .../error_reporting/nice_region_error/mod.rs | 2 +- .../nice_region_error/named_anon_conflict.rs | 6 +- .../nice_region_error/placeholder_error.rs | 10 +- .../src/infer/error_reporting/note.rs | 6 +- compiler/rustc_infer/src/infer/mod.rs | 10 +- .../src/traits/error_reporting/mod.rs | 6 +- compiler/rustc_lint/src/context.rs | 22 +- compiler/rustc_lint/src/levels.rs | 25 +- .../rustc_macros/src/session_diagnostic.rs | 2 +- compiler/rustc_metadata/src/native_libs.rs | 4 +- compiler/rustc_middle/src/lint.rs | 6 +- .../rustc_middle/src/mir/interpret/error.rs | 5 +- .../src/thir/pattern/check_match.rs | 10 +- .../src/check_const_item_mutation.rs | 2 +- compiler/rustc_parse/src/lexer/mod.rs | 6 +- .../src/lexer/unescape_error_reporting.rs | 26 +- .../rustc_parse/src/parser/diagnostics.rs | 32 ++- compiler/rustc_parse/src/parser/expr.rs | 11 +- compiler/rustc_parse/src/parser/item.rs | 4 +- compiler/rustc_parse/src/parser/mod.rs | 6 +- compiler/rustc_parse/src/parser/pat.rs | 6 +- compiler/rustc_parse/src/parser/stmt.rs | 7 +- compiler/rustc_parse/src/parser/ty.rs | 3 +- compiler/rustc_passes/src/check_attr.rs | 2 +- compiler/rustc_passes/src/check_const.rs | 4 +- compiler/rustc_passes/src/intrinsicck.rs | 2 +- .../rustc_query_system/src/query/config.rs | 4 +- compiler/rustc_query_system/src/query/job.rs | 4 +- .../rustc_query_system/src/query/plumbing.rs | 4 +- .../rustc_resolve/src/build_reduced_graph.rs | 5 +- compiler/rustc_resolve/src/diagnostics.rs | 9 +- .../rustc_resolve/src/late/diagnostics.rs | 8 +- compiler/rustc_resolve/src/late/lifetimes.rs | 1 + compiler/rustc_resolve/src/lib.rs | 4 +- compiler/rustc_session/src/parse.rs | 6 +- compiler/rustc_session/src/session.rs | 50 ++-- .../src/traits/error_reporting/mod.rs | 4 +- .../src/traits/error_reporting/suggestions.rs | 7 +- .../src/traits/specialize/mod.rs | 2 +- compiler/rustc_typeck/src/astconv/mod.rs | 4 +- compiler/rustc_typeck/src/check/cast.rs | 2 +- compiler/rustc_typeck/src/check/check.rs | 20 +- compiler/rustc_typeck/src/check/coercion.rs | 4 +- compiler/rustc_typeck/src/check/demand.rs | 12 +- compiler/rustc_typeck/src/check/expr.rs | 35 +-- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 2 +- .../rustc_typeck/src/check/method/suggest.rs | 6 +- compiler/rustc_typeck/src/check/pat.rs | 18 +- compiler/rustc_typeck/src/check/wfcheck.rs | 20 +- .../rustc_typeck/src/coherence/builtin.rs | 2 +- compiler/rustc_typeck/src/coherence/orphan.rs | 6 +- compiler/rustc_typeck/src/collect.rs | 30 +-- .../src/impl_wf_check/min_specialization.rs | 11 +- .../rustc_typeck/src/structured_errors.rs | 16 +- .../missing_cast_for_variadic_arg.rs | 9 +- .../structured_errors/sized_unsized_cast.rs | 9 +- .../wrong_number_of_generic_args.rs | 8 +- src/librustdoc/lib.rs | 8 +- 83 files changed, 842 insertions(+), 471 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 7140cda8e4e51..e2b6a48a9e867 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -1,9 +1,13 @@ -use rustc_errors::{struct_span_err, DiagnosticBuilder, DiagnosticId}; +use rustc_errors::{struct_span_err, DiagnosticBuilder, DiagnosticId, ErrorReported}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::{MultiSpan, Span}; impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { - crate fn cannot_move_when_borrowed(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx> { + crate fn cannot_move_when_borrowed( + &self, + span: Span, + desc: &str, + ) -> DiagnosticBuilder<'cx, ErrorReported> { struct_span_err!(self, span, E0505, "cannot move out of {} because it is borrowed", desc,) } @@ -13,7 +17,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { desc: &str, borrow_span: Span, borrow_desc: &str, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let mut err = struct_span_err!( self, span, @@ -32,7 +36,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { span: Span, verb: &str, desc: &str, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { struct_span_err!( self, span, @@ -51,7 +55,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { old_loan_span: Span, old_opt_via: &str, old_load_end_span: Option, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg) }; let mut err = struct_span_err!( @@ -99,7 +103,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { desc: &str, old_loan_span: Span, old_load_end_span: Option, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let mut err = struct_span_err!( self, new_loan_span, @@ -132,7 +136,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { noun_old: &str, old_opt_via: &str, previous_end_span: Option, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let mut err = struct_span_err!( self, new_loan_span, @@ -164,7 +168,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { old_opt_via: &str, previous_end_span: Option, second_borrow_desc: &str, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let mut err = struct_span_err!( self, new_loan_span, @@ -200,7 +204,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { kind_old: &str, msg_old: &str, old_load_end_span: Option, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg) }; let mut err = struct_span_err!( @@ -243,7 +247,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { span: Span, borrow_span: Span, desc: &str, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let mut err = struct_span_err!( self, span, @@ -262,12 +266,12 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { span: Span, desc: &str, is_arg: bool, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" }; struct_span_err!(self, span, E0384, "cannot assign {} {}", msg, desc) } - crate fn cannot_assign(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx> { + crate fn cannot_assign(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx, ErrorReported> { struct_span_err!(self, span, E0594, "cannot assign to {}", desc) } @@ -275,7 +279,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { &self, move_from_span: Span, move_from_desc: &str, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc,) } @@ -287,7 +291,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { move_from_span: Span, ty: Ty<'_>, is_index: Option, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let type_name = match (&ty.kind(), is_index) { (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array", (&ty::Slice(_), _) => "slice", @@ -309,7 +313,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { &self, move_from_span: Span, container_ty: Ty<'_>, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let mut err = struct_span_err!( self, move_from_span, @@ -327,7 +331,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { verb: &str, optional_adverb_for_moved: &str, moved_path: Option, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let moved_path = moved_path.map(|mp| format!(": `{}`", mp)).unwrap_or_default(); struct_span_err!( @@ -346,7 +350,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { span: Span, path: &str, reason: &str, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{}", path, reason,) } @@ -357,7 +361,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { immutable_place: &str, immutable_section: &str, action: &str, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let mut err = struct_span_err!( self, mutate_span, @@ -376,7 +380,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { &self, span: Span, yield_span: Span, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let mut err = struct_span_err!( self, span, @@ -387,7 +391,10 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> DiagnosticBuilder<'cx> { + crate fn cannot_borrow_across_destructor( + &self, + borrow_span: Span, + ) -> DiagnosticBuilder<'cx, ErrorReported> { struct_span_err!( self, borrow_span, @@ -400,7 +407,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { &self, span: Span, path: &str, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { struct_span_err!(self, span, E0597, "{} does not live long enough", path,) } @@ -410,7 +417,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { return_kind: &str, reference_desc: &str, path_desc: &str, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let mut err = struct_span_err!( self, span, @@ -435,7 +442,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { closure_kind: &str, borrowed_path: &str, capture_span: Span, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let mut err = struct_span_err!( self, closure_span, @@ -454,11 +461,14 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { crate fn thread_local_value_does_not_live_long_enough( &self, span: Span, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { struct_span_err!(self, span, E0712, "thread-local variable borrowed past end of function",) } - crate fn temporary_value_borrowed_for_too_long(&self, span: Span) -> DiagnosticBuilder<'cx> { + crate fn temporary_value_borrowed_for_too_long( + &self, + span: Span, + ) -> DiagnosticBuilder<'cx, ErrorReported> { struct_span_err!(self, span, E0716, "temporary value dropped while borrowed",) } @@ -467,7 +477,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { sp: S, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { self.infcx.tcx.sess.struct_span_err_with_code(sp, msg, code) } } @@ -476,7 +486,7 @@ crate fn borrowed_data_escapes_closure<'tcx>( tcx: TyCtxt<'tcx>, escape_span: Span, escapes_from: &str, -) -> DiagnosticBuilder<'tcx> { +) -> DiagnosticBuilder<'tcx, ErrorReported> { struct_span_err!( tcx.sess, escape_span, diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 2a906e41b8cd5..3ef002bf74027 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -1,4 +1,4 @@ -use rustc_errors::DiagnosticBuilder; +use rustc_errors::{DiagnosticBuilder, ErrorReported}; use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError; use rustc_infer::infer::region_constraints::Constraint; @@ -120,7 +120,11 @@ impl<'tcx, F, G> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::Custo trait TypeOpInfo<'tcx> { /// Returns an error to be reported if rerunning the type op fails to /// recover the error's cause. - fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx>; + fn fallback_error( + &self, + tcx: TyCtxt<'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported>; fn base_universe(&self) -> ty::UniverseIndex; @@ -130,7 +134,7 @@ trait TypeOpInfo<'tcx> { cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option>; + ) -> Option>; fn report_error( &self, @@ -188,7 +192,11 @@ struct PredicateQuery<'tcx> { } impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { - fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn fallback_error( + &self, + tcx: TyCtxt<'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = tcx.sess.struct_span_err(span, "higher-ranked lifetime error"); err.note(&format!("could not prove {}", self.canonical_query.value.value.predicate)); err @@ -204,7 +212,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { tcx.infer_ctxt().enter_with_canonical( cause.span, &self.canonical_query, @@ -231,7 +239,11 @@ impl<'tcx, T> TypeOpInfo<'tcx> for NormalizeQuery<'tcx, T> where T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx, { - fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn fallback_error( + &self, + tcx: TyCtxt<'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = tcx.sess.struct_span_err(span, "higher-ranked lifetime error"); err.note(&format!("could not normalize `{}`", self.canonical_query.value.value.value)); err @@ -247,7 +259,7 @@ where cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { tcx.infer_ctxt().enter_with_canonical( cause.span, &self.canonical_query, @@ -288,7 +300,11 @@ struct AscribeUserTypeQuery<'tcx> { } impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { - fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn fallback_error( + &self, + tcx: TyCtxt<'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests, // and is only the fallback when the nice error fails. Consider improving this some more. tcx.sess.struct_span_err(span, "higher-ranked lifetime error") @@ -304,7 +320,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { tcx.infer_ctxt().enter_with_canonical( cause.span, &self.canonical_query, @@ -329,7 +345,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>( infcx: &InferCtxt<'_, 'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, -) -> Option> { +) -> Option> { let tcx = infcx.tcx; // We generally shouldn't have errors here because the query was diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 3da94dd28b108..cd1f73d529818 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1,7 +1,7 @@ use either::Either; use rustc_const_eval::util::{CallDesugaringKind, CallKind}; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; @@ -507,7 +507,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { location: Location, (place, _span): (Place<'tcx>, Span), borrow: &BorrowData<'tcx>, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let borrow_spans = self.retrieve_borrow_spans(borrow); let borrow_span = borrow_spans.args_or_use(); @@ -554,7 +554,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { (place, span): (Place<'tcx>, Span), gen_borrow_kind: BorrowKind, issued_borrow: &BorrowData<'tcx>, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let issued_spans = self.retrieve_borrow_spans(issued_borrow); let issued_span = issued_spans.args_or_use(); @@ -1120,7 +1120,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { drop_span: Span, borrow_spans: UseSpans<'tcx>, explanation: BorrowExplanation, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { debug!( "report_local_value_does_not_live_long_enough(\ {:?}, {:?}, {:?}, {:?}, {:?}\ @@ -1298,7 +1298,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, drop_span: Span, borrow_span: Span, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { debug!( "report_thread_local_value_does_not_live_long_enough(\ {:?}, {:?}\ @@ -1325,7 +1325,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow_spans: UseSpans<'tcx>, proper_span: Span, explanation: BorrowExplanation, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { debug!( "report_temporary_value_does_not_live_long_enough(\ {:?}, {:?}, {:?}, {:?}\ @@ -1384,7 +1384,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return_span: Span, category: ConstraintCategory, opt_place_desc: Option<&String>, - ) -> Option> { + ) -> Option> { let return_kind = match category { ConstraintCategory::Return(_) => "return", ConstraintCategory::Yield => "yield", @@ -1483,7 +1483,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { category: ConstraintCategory, constraint_span: Span, captured_var: &str, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let tcx = self.infcx.tcx; let args_span = use_span.args_or_use(); @@ -1560,7 +1560,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { upvar_span: Span, upvar_name: &str, escape_span: Span, - ) -> DiagnosticBuilder<'cx> { + ) -> DiagnosticBuilder<'cx, ErrorReported> { let tcx = self.infcx.tcx; let (_, escapes_from) = tcx.article_and_description(self.mir_def_id().to_def_id()); diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 71dd6cc9144be..66f4c28a36d66 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -1,5 +1,5 @@ use rustc_const_eval::util::CallDesugaringKind; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported}; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::*; use rustc_middle::ty; @@ -271,7 +271,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { &mut self, place: Place<'tcx>, span: Span, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'a, ErrorReported> { let description = if place.projection.len() == 1 { format!("static item {}", self.describe_any_place(place.as_ref())) } else { @@ -293,7 +293,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { deref_target_place: Place<'tcx>, span: Span, use_spans: Option>, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'a, ErrorReported> { // Inspect the type of the content behind the // borrow to provide feedback about why this // was a move rather than a copy. diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs index 72415cb51a0cb..de50f907eff6f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs @@ -256,6 +256,6 @@ impl OutlivesSuggestionBuilder { diag.sort_span = mir_span.shrink_to_hi(); // Buffer the diagnostic - mbcx.buffer_error(diag); + mbcx.buffer_non_error_diag(diag); } } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 5ac6ea33a26e3..64f05f6004f53 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -1,6 +1,6 @@ //! Error reporting machinery for lifetime errors. -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported}; use rustc_infer::infer::{ error_reporting::nice_region_error::NiceRegionError, error_reporting::unexpected_hidden_region_diagnostic, NllRegionVariableOrigin, @@ -392,7 +392,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { &self, errci: &ErrorConstraintInfo, kind: ReturnConstraint, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; let mut diag = self @@ -469,7 +469,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// LL | ref_obj(x) /// | ^^^^^^^^^^ `x` escapes the function body here /// ``` - fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> { + fn report_escaping_data_error( + &self, + errci: &ErrorConstraintInfo, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let ErrorConstraintInfo { span, category, .. } = errci; let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( @@ -570,7 +573,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it /// | is returning data with lifetime `'b` /// ``` - fn report_general_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> { + fn report_general_error( + &self, + errci: &ErrorConstraintInfo, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let ErrorConstraintInfo { fr, fr_is_local, diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 04f446ebcf104..d9dcc27da0a78 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -398,7 +398,7 @@ fn do_mir_borrowck<'a, 'tcx>( diag.message = initial_diag.styled_message().clone(); diag.span = initial_diag.span.clone(); - mbcx.buffer_error(diag); + mbcx.buffer_non_error_diag(diag); }, ); initial_diag.cancel(); @@ -2293,8 +2293,8 @@ mod error { /// when errors in the map are being re-added to the error buffer so that errors with the /// same primary span come out in a consistent order. buffered_move_errors: - BTreeMap, (PlaceRef<'tcx>, DiagnosticBuilder<'tcx>)>, - /// Errors to be reported buffer + BTreeMap, (PlaceRef<'tcx>, DiagnosticBuilder<'tcx, ErrorReported>)>, + /// Diagnostics to be reported buffer. buffered: Vec, /// Set to Some if we emit an error during borrowck tainted_by_errors: Option, @@ -2309,25 +2309,35 @@ mod error { } } - pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_>) { + // 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<'_, ErrorReported>) { self.tainted_by_errors = Some(ErrorReported {}); t.buffer(&mut self.buffered); } + pub fn buffer_non_error_diag(&mut self, t: DiagnosticBuilder<'_, ()>) { + t.buffer(&mut self.buffered); + } + pub fn set_tainted_by_errors(&mut self) { self.tainted_by_errors = Some(ErrorReported {}); } } impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { - pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_>) { + pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorReported>) { self.errors.buffer_error(t); } + pub fn buffer_non_error_diag(&mut self, t: DiagnosticBuilder<'_, ()>) { + self.errors.buffer_non_error_diag(t); + } + pub fn buffer_move_error( &mut self, move_out_indices: Vec, - place_and_err: (PlaceRef<'tcx>, DiagnosticBuilder<'tcx>), + place_and_err: (PlaceRef<'tcx>, DiagnosticBuilder<'tcx, ErrorReported>), ) -> bool { if let Some((_, diag)) = self.errors.buffered_move_errors.insert(move_out_indices, place_and_err) @@ -2365,7 +2375,7 @@ mod error { pub fn has_move_error( &self, move_out_indices: &[MoveOutIndex], - ) -> Option<&(PlaceRef<'tcx>, DiagnosticBuilder<'cx>)> { + ) -> Option<&(PlaceRef<'tcx>, DiagnosticBuilder<'cx, ErrorReported>)> { self.errors.buffered_move_errors.get(move_out_indices) } } diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index a16bdf286738c..a2736fd115664 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -417,7 +417,7 @@ pub(super) fn dump_annotation<'a, 'tcx>( err.note(&format!("Inferred opaque type values:\n{:#?}", opaque_type_values)); } - errors.buffer_error(err); + errors.buffer_non_error_diag(err); } fn for_each_region_constraint( diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index ac37c4973d870..57ef46475ddd8 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -3,7 +3,7 @@ use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{Applicability, DiagnosticBuilder}; +use rustc_errors::{Applicability, PResult}; use rustc_expand::base::{self, *}; use rustc_parse::parser::Parser; use rustc_parse_format as parse; @@ -30,7 +30,7 @@ fn parse_args<'a>( sp: Span, tts: TokenStream, is_global_asm: bool, -) -> Result> { +) -> PResult<'a, AsmArgs> { let mut p = ecx.new_parser_from_tts(tts); let sess = &ecx.sess.parse_sess; parse_asm_args(&mut p, sess, sp, is_global_asm) @@ -43,7 +43,7 @@ pub fn parse_asm_args<'a>( sess: &'a ParseSess, sp: Span, is_global_asm: bool, -) -> Result> { +) -> PResult<'a, AsmArgs> { let diag = &sess.span_diagnostic; if p.token == token::Eof { @@ -390,7 +390,7 @@ fn parse_options<'a>( p: &mut Parser<'a>, args: &mut AsmArgs, is_global_asm: bool, -) -> Result<(), DiagnosticBuilder<'a>> { +) -> PResult<'a, ()> { let span_start = p.prev_token.span; p.expect(&token::OpenDelim(token::DelimToken::Paren))?; @@ -431,10 +431,7 @@ fn parse_options<'a>( Ok(()) } -fn parse_clobber_abi<'a>( - p: &mut Parser<'a>, - args: &mut AsmArgs, -) -> Result<(), DiagnosticBuilder<'a>> { +fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a, ()> { let span_start = p.prev_token.span; p.expect(&token::OpenDelim(token::DelimToken::Paren))?; @@ -501,7 +498,7 @@ fn parse_clobber_abi<'a>( fn parse_reg<'a>( p: &mut Parser<'a>, explicit_reg: &mut bool, -) -> Result> { +) -> PResult<'a, ast::InlineAsmRegOrRegClass> { p.expect(&token::OpenDelim(token::DelimToken::Paren))?; let result = match p.token.uninterpolate().kind { token::Ident(name, false) => ast::InlineAsmRegOrRegClass::RegClass(name), diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index 9a45dec55f30b..a984980dea9bf 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -4,7 +4,7 @@ use rustc_ast::token; use rustc_ast::tokenstream::{DelimSpan, TokenStream}; use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust; -use rustc_errors::{Applicability, DiagnosticBuilder}; +use rustc_errors::{Applicability, PResult}; use rustc_expand::base::*; use rustc_parse::parser::Parser; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -83,11 +83,7 @@ struct Assert { custom_message: Option, } -fn parse_assert<'a>( - cx: &mut ExtCtxt<'a>, - sp: Span, - stream: TokenStream, -) -> Result> { +fn parse_assert<'a>(cx: &mut ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PResult<'a, Assert> { let mut parser = cx.new_parser_from_tts(stream); if parser.token == token::Eof { diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index 4c00162b556b8..1e1cf917c6093 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -6,7 +6,7 @@ use rustc_ast as ast; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; use rustc_attr as attr; -use rustc_errors::DiagnosticBuilder; +use rustc_errors::PResult; use rustc_expand::base::{self, *}; use rustc_span::Span; @@ -29,11 +29,7 @@ pub fn expand_cfg( } } -fn parse_cfg<'a>( - cx: &mut ExtCtxt<'a>, - sp: Span, - tts: TokenStream, -) -> Result> { +fn parse_cfg<'a>(cx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a, ast::MetaItem> { let mut p = cx.new_parser_from_tts(tts); if p.token == token::Eof { diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 6141d00f69712..31213412d45f2 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -7,7 +7,7 @@ use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{token, BlockCheckMode, UnsafeSource}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, Applicability, DiagnosticBuilder}; +use rustc_errors::{pluralize, Applicability, PResult}; use rustc_expand::base::{self, *}; use rustc_parse_format as parse; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -130,7 +130,7 @@ fn parse_args<'a>( ecx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream, -) -> Result<(P, Vec>, FxHashMap), DiagnosticBuilder<'a>> { +) -> PResult<'a, (P, Vec>, FxHashMap)> { let mut args = Vec::>::new(); let mut names = FxHashMap::::default(); diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 418729e78436f..7ee0fb9b817ca 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -376,9 +376,13 @@ fn get_test_runner( match &*meta_list { [single] => match single.meta_item() { Some(meta_item) if meta_item.is_word() => return Some(meta_item.path.clone()), - _ => sd.struct_span_err(span, "`test_runner` argument must be a path").emit(), + _ => { + sd.struct_span_err(span, "`test_runner` argument must be a path").emit(); + } }, - _ => sd.struct_span_err(span, "`#![test_runner(..)]` accepts exactly 1 argument").emit(), + _ => { + sd.struct_span_err(span, "`#![test_runner(..)]` accepts exactly 1 argument").emit(); + } } None } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 7679b7eb2dd42..55ea0c4d72706 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1753,7 +1753,7 @@ impl SharedEmitterMain { let msg = msg.strip_prefix("error: ").unwrap_or(&msg); let mut err = match level { - Level::Error { lint: false } => sess.struct_err(&msg), + Level::Error { lint: false } => sess.struct_err(&msg).forget_guarantee(), Level::Warning => sess.struct_warn(&msg), Level::Note => sess.struct_note_without_error(&msg), _ => bug!("Invalid inline asm diagnostic level"), diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 89a0f8245e5fb..3bd092263c13a 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -1,7 +1,7 @@ use std::error::Error; use std::fmt; -use rustc_errors::{DiagnosticBuilder, ErrorReported}; +use rustc_errors::Diagnostic; use rustc_hir as hir; use rustc_middle::mir::AssertKind; use rustc_middle::ty::{layout::LayoutError, query::TyCtxtAt, ConstInt}; @@ -94,13 +94,13 @@ impl<'tcx> ConstEvalErr<'tcx> { &self, tcx: TyCtxtAt<'tcx>, message: &str, - emit: impl FnOnce(DiagnosticBuilder<'_>), + decorate: impl FnOnce(&mut Diagnostic), ) -> ErrorHandled { - self.struct_generic(tcx, message, emit, None) + self.struct_generic(tcx, message, decorate, None) } pub fn report_as_error(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ErrorHandled { - self.struct_error(tcx, message, |mut e| e.emit()) + self.struct_error(tcx, message, |_| {}) } pub fn report_as_lint( @@ -113,7 +113,7 @@ impl<'tcx> ConstEvalErr<'tcx> { self.struct_generic( tcx, message, - |mut lint: DiagnosticBuilder<'_>| { + |lint: &mut Diagnostic| { // Apply the span. if let Some(span) = span { let primary_spans = lint.span.primary_spans().to_vec(); @@ -127,7 +127,6 @@ impl<'tcx> ConstEvalErr<'tcx> { } } } - lint.emit(); }, Some(lint_root), ) @@ -136,9 +135,8 @@ impl<'tcx> ConstEvalErr<'tcx> { /// Create a diagnostic for this const eval error. /// /// Sets the message passed in via `message` and adds span labels with detailed error - /// information before handing control back to `emit` to do any final processing. - /// It's the caller's responsibility to call emit(), stash(), etc. within the `emit` - /// function to dispose of the diagnostic properly. + /// information before handing control back to `decorate` to do any final annotations, + /// after which the diagnostic is emitted. /// /// If `lint_root.is_some()` report it as a lint, else report it as a hard error. /// (Except that for some errors, we ignore all that -- see `must_error` below.) @@ -146,10 +144,10 @@ impl<'tcx> ConstEvalErr<'tcx> { &self, tcx: TyCtxtAt<'tcx>, message: &str, - emit: impl FnOnce(DiagnosticBuilder<'_>), + decorate: impl FnOnce(&mut Diagnostic), lint_root: Option, ) -> ErrorHandled { - let finish = |mut err: DiagnosticBuilder<'_>, span_msg: Option| { + let finish = |err: &mut Diagnostic, span_msg: Option| { trace!("reporting const eval failure at {:?}", self.span); if let Some(span_msg) = span_msg { err.span_label(self.span, span_msg); @@ -188,8 +186,8 @@ impl<'tcx> ConstEvalErr<'tcx> { } flush_last_line(last_frame, times); } - // Let the caller finish the job. - emit(err) + // Let the caller attach any additional information it wants. + decorate(err); }; // Special handling for certain errors @@ -206,8 +204,9 @@ impl<'tcx> ConstEvalErr<'tcx> { // The `message` makes little sense here, this is a more serious error than the // caller thinks anyway. // See . - finish(struct_error(tcx, &self.error.to_string()), None); - return ErrorHandled::Reported(ErrorReported); + let mut err = struct_error(tcx, &self.error.to_string()); + finish(&mut err, None); + return ErrorHandled::Reported(err.emit()); } _ => {} }; @@ -223,13 +222,18 @@ impl<'tcx> ConstEvalErr<'tcx> { rustc_session::lint::builtin::CONST_ERR, hir_id, tcx.span, - |lint| finish(lint.build(message), Some(err_msg)), + |lint| { + let mut lint = lint.build(message); + finish(&mut lint, Some(err_msg)); + lint.emit(); + }, ); ErrorHandled::Linted } else { // Report as hard error. - finish(struct_error(tcx, message), Some(err_msg)); - ErrorHandled::Reported(ErrorReported) + let mut err = struct_error(tcx, message); + finish(&mut err, Some(err_msg)); + ErrorHandled::Reported(err.emit()) } } } diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 533c32f807df6..dad572741049b 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -361,7 +361,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( Err(err.struct_error( ecx.tcx, "it is undefined behavior to use this value", - |mut diag| { + |diag| { diag.note(note_on_undefined_behavior_error()); diag.note(&format!( "the raw bytes of the constant ({}", @@ -370,7 +370,6 @@ pub fn eval_to_allocation_raw_provider<'tcx>( ecx.tcx.global_alloc(alloc_id).unwrap_memory() ) )); - diag.emit(); }, )) } else { diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index a9b1b40ea2929..5738b38d443a0 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -1,6 +1,6 @@ //! Concrete error types for all operations which may be invalid in a certain const context. -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; @@ -47,7 +47,11 @@ pub trait NonConstOp<'tcx>: std::fmt::Debug { DiagnosticImportance::Primary } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx>; + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported>; } #[derive(Debug)] @@ -61,7 +65,11 @@ impl<'tcx> NonConstOp<'tcx> for FloatingPointOp { } } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { feature_err( &ccx.tcx.sess.parse_sess, sym::const_fn_floating_point_arithmetic, @@ -75,7 +83,11 @@ impl<'tcx> NonConstOp<'tcx> for FloatingPointOp { #[derive(Debug)] pub struct FnCallIndirect; impl<'tcx> NonConstOp<'tcx> for FnCallIndirect { - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { ccx.tcx.sess.struct_span_err(span, "function pointers are not allowed in const fn") } } @@ -91,7 +103,11 @@ pub struct FnCallNonConst<'tcx> { } impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + _: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let FnCallNonConst { caller, callee, substs, span, from_hir_call } = *self; let ConstCx { tcx, param_env, .. } = *ccx; @@ -312,7 +328,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { pub struct FnCallUnstable(pub DefId, pub Option); impl<'tcx> NonConstOp<'tcx> for FnCallUnstable { - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let FnCallUnstable(def_id, feature) = *self; let mut err = ccx.tcx.sess.struct_span_err( @@ -346,7 +366,11 @@ impl<'tcx> NonConstOp<'tcx> for FnPtrCast { } } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { feature_err( &ccx.tcx.sess.parse_sess, sym::const_fn_fn_ptr_basics, @@ -367,7 +391,11 @@ impl<'tcx> NonConstOp<'tcx> for Generator { } } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let msg = format!("{}s are not allowed in {}s", self.0, ccx.const_kind()); if let hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) = self.0 { feature_err(&ccx.tcx.sess.parse_sess, sym::const_async_blocks, span, &msg) @@ -380,7 +408,11 @@ impl<'tcx> NonConstOp<'tcx> for Generator { #[derive(Debug)] pub struct HeapAllocation; impl<'tcx> NonConstOp<'tcx> for HeapAllocation { - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = struct_span_err!( ccx.tcx.sess, span, @@ -404,7 +436,11 @@ impl<'tcx> NonConstOp<'tcx> for HeapAllocation { #[derive(Debug)] pub struct InlineAsm; impl<'tcx> NonConstOp<'tcx> for InlineAsm { - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { struct_span_err!( ccx.tcx.sess, span, @@ -420,7 +456,11 @@ pub struct LiveDrop { pub dropped_at: Option, } impl<'tcx> NonConstOp<'tcx> for LiveDrop { - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = struct_span_err!( ccx.tcx.sess, span, @@ -448,7 +488,11 @@ impl<'tcx> NonConstOp<'tcx> for TransientCellBorrow { // not additionally emit a feature gate error if activating the feature gate won't work. DiagnosticImportance::Secondary } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { feature_err( &ccx.tcx.sess.parse_sess, sym::const_refs_to_cell, @@ -464,7 +508,11 @@ impl<'tcx> NonConstOp<'tcx> for TransientCellBorrow { /// it in the future for static items. pub struct CellBorrow; impl<'tcx> NonConstOp<'tcx> for CellBorrow { - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = struct_span_err!( ccx.tcx.sess, span, @@ -511,7 +559,11 @@ impl<'tcx> NonConstOp<'tcx> for MutBorrow { DiagnosticImportance::Secondary } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let raw = match self.0 { hir::BorrowKind::Raw => "raw ", hir::BorrowKind::Ref => "", @@ -550,7 +602,11 @@ impl<'tcx> NonConstOp<'tcx> for TransientMutBorrow { Status::Unstable(sym::const_mut_refs) } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let raw = match self.0 { hir::BorrowKind::Raw => "raw ", hir::BorrowKind::Ref => "", @@ -577,7 +633,11 @@ impl<'tcx> NonConstOp<'tcx> for MutDeref { DiagnosticImportance::Secondary } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { feature_err( &ccx.tcx.sess.parse_sess, sym::const_mut_refs, @@ -591,7 +651,11 @@ impl<'tcx> NonConstOp<'tcx> for MutDeref { #[derive(Debug)] pub struct PanicNonStr; impl<'tcx> NonConstOp<'tcx> for PanicNonStr { - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { ccx.tcx.sess.struct_span_err( span, "argument to `panic!()` in a const context must have type `&str`", @@ -605,7 +669,11 @@ impl<'tcx> NonConstOp<'tcx> for PanicNonStr { #[derive(Debug)] pub struct RawPtrComparison; impl<'tcx> NonConstOp<'tcx> for RawPtrComparison { - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = ccx .tcx .sess @@ -625,7 +693,11 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref { Status::Unstable(sym::const_mut_refs) } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { feature_err( &ccx.tcx.sess.parse_sess, sym::const_mut_refs, @@ -641,7 +713,11 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref { #[derive(Debug)] pub struct RawPtrToIntCast; impl<'tcx> NonConstOp<'tcx> for RawPtrToIntCast { - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = ccx .tcx .sess @@ -666,7 +742,11 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess { } } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = struct_span_err!( ccx.tcx.sess, span, @@ -692,7 +772,11 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess { #[derive(Debug)] pub struct ThreadLocalAccess; impl<'tcx> NonConstOp<'tcx> for ThreadLocalAccess { - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { struct_span_err!( ccx.tcx.sess, span, @@ -723,7 +807,11 @@ pub mod ty { } } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { feature_err( &ccx.tcx.sess.parse_sess, sym::const_mut_refs, @@ -753,7 +841,11 @@ pub mod ty { } } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { feature_err( &ccx.tcx.sess.parse_sess, sym::const_fn_fn_ptr_basics, @@ -770,7 +862,11 @@ pub mod ty { Status::Unstable(sym::const_impl_trait) } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { feature_err( &ccx.tcx.sess.parse_sess, sym::const_impl_trait, @@ -800,7 +896,11 @@ pub mod ty { } } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = feature_err( &ccx.tcx.sess.parse_sess, sym::const_fn_trait_bound, @@ -839,7 +939,11 @@ pub mod ty { } } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = feature_err( &ccx.tcx.sess.parse_sess, sym::const_fn_trait_bound, @@ -866,7 +970,11 @@ pub mod ty { Status::Unstable(sym::const_trait_bound_opt_out) } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + fn build_error( + &self, + ccx: &ConstCx<'_, 'tcx>, + span: Span, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { feature_err( &ccx.tcx.sess.parse_sess, sym::const_trait_bound_opt_out, diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 7978e1cc162b8..49305d2268417 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -1,9 +1,10 @@ -use crate::{Diagnostic, DiagnosticId, DiagnosticStyledString}; +use crate::{Diagnostic, DiagnosticId, DiagnosticStyledString, ErrorReported}; use crate::{Handler, Level, StashKey}; use rustc_lint_defs::Applicability; use rustc_span::{MultiSpan, Span}; use std::fmt::{self, Debug}; +use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use std::thread::panicking; use tracing::debug; @@ -15,7 +16,24 @@ use tracing::debug; /// extending `HandlerFlags`, accessed via `self.handler.flags`. #[must_use] #[derive(Clone)] -pub struct DiagnosticBuilder<'a> { +pub struct DiagnosticBuilder<'a, G: EmissionGuarantee> { + inner: DiagnosticBuilderInner<'a>, + _marker: PhantomData, +} + +/// This type exists only for `DiagnosticBuilder::forget_guarantee`, because it: +/// 1. lacks the `G` parameter and therefore `DiagnosticBuilder` can be +/// converted into `DiagnosticBuilder` while reusing the `inner` field +/// 2. can implement the `Drop` "bomb" instead of `DiagnosticBuilder`, as it +/// contains all of the data (`state` + `diagnostic`) of `DiagnosticBuilder` +/// +/// The `diagnostic` field is not `Copy` and can't be moved out of whichever +/// type implements the `Drop` "bomb", but because of the above two facts, that +/// never needs to happen - instead, the whole `inner: DiagnosticBuilderInner` +/// can be moved out of a `DiagnosticBuilder` and into another. +#[must_use] +#[derive(Clone)] +struct DiagnosticBuilderInner<'a> { state: DiagnosticBuilderState<'a>, /// `Diagnostic` is a large type, and `DiagnosticBuilder` is often used as a @@ -38,8 +56,8 @@ enum DiagnosticBuilderState<'a> { /// assumed that `.emit()` was previously called, to end up in this state. /// /// While this is also used by `.cancel()`, this state is only observed by - /// the `Drop` `impl` of `DiagnosticBuilder`, as `.cancel()` takes `self` - /// by-value specifically to prevent any attempts to `.emit()`. + /// the `Drop` `impl` of `DiagnosticBuilderInner`, as `.cancel()` takes + /// `self` by-value specifically to prevent any attempts to `.emit()`. /// // FIXME(eddyb) currently this doesn't prevent extending the `Diagnostic`, // despite that being potentially lossy, if important information is added @@ -53,6 +71,133 @@ rustc_data_structures::static_assert_size!( std::mem::size_of::<&Handler>() ); +/// Trait for types that `DiagnosticBuilder::emit` can return as a "guarantee" +/// (or "proof") token that the emission happened. +pub trait EmissionGuarantee: Sized { + /// Implementation of `DiagnosticBuilder::emit`, fully controlled by each + /// `impl` of `EmissionGuarantee`, to make it impossible to create a value + /// of `Self` without actually performing the emission. + #[track_caller] + fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self; +} + +/// Private module for sealing the `IsError` helper trait. +mod sealed_level_is_error { + use crate::Level; + + /// Sealed helper trait for statically checking that a `Level` is an error. + crate trait IsError {} + + impl IsError<{ Level::Bug }> for () {} + impl IsError<{ Level::DelayedBug }> for () {} + impl IsError<{ Level::Fatal }> for () {} + // NOTE(eddyb) `Level::Error { lint: true }` is also an error, but lints + // don't need error guarantees, as their levels are always dynamic. + impl IsError<{ Level::Error { lint: false } }> for () {} +} + +impl<'a> DiagnosticBuilder<'a, ErrorReported> { + /// Convenience function for internal use, clients should use one of the + /// `struct_*` methods on [`Handler`]. + crate fn new_guaranteeing_error(handler: &'a Handler, message: &str) -> Self + where + (): sealed_level_is_error::IsError, + { + Self { + inner: DiagnosticBuilderInner { + state: DiagnosticBuilderState::Emittable(handler), + diagnostic: Box::new(Diagnostic::new_with_code(L, None, message)), + }, + _marker: PhantomData, + } + } + + /// Discard the guarantee `.emit()` would return, in favor of having the + /// type `DiagnosticBuilder<'a, ()>`. This may be necessary whenever there + /// is a common codepath handling both errors and warnings. + pub fn forget_guarantee(self) -> DiagnosticBuilder<'a, ()> { + DiagnosticBuilder { inner: self.inner, _marker: PhantomData } + } +} + +// FIXME(eddyb) make `ErrorReported` impossible to create outside `.emit()`. +impl EmissionGuarantee for ErrorReported { + fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self { + match db.inner.state { + // First `.emit()` call, the `&Handler` is still available. + DiagnosticBuilderState::Emittable(handler) => { + db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; + + 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` + // can be overwritten with a new one, thanks to `DerefMut`. + assert!( + db.inner.diagnostic.is_error(), + "emitted non-error ({:?}) diagnostic \ + from `DiagnosticBuilder`", + db.inner.diagnostic.level, + ); + ErrorReported + } + // `.emit()` was previously called, disallowed from repeating it, + // but can take advantage of the previous `.emit()`'s guarantee + // still being applicable (i.e. as a form of idempotency). + DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => { + // Only allow a guarantee if the `level` wasn't switched to a + // non-error - the field isn't `pub`, but the whole `Diagnostic` + // can be overwritten with a new one, thanks to `DerefMut`. + assert!( + db.inner.diagnostic.is_error(), + "`DiagnosticBuilder`'s diagnostic \ + became non-error ({:?}), after original `.emit()`", + db.inner.diagnostic.level, + ); + ErrorReported + } + } + } +} + +impl<'a> DiagnosticBuilder<'a, ()> { + /// Convenience function for internal use, clients should use one of the + /// `struct_*` methods on [`Handler`]. + crate fn new(handler: &'a Handler, level: Level, message: &str) -> Self { + let diagnostic = Diagnostic::new_with_code(level, None, message); + Self::new_diagnostic(handler, diagnostic) + } + + /// Creates a new `DiagnosticBuilder` with an already constructed + /// diagnostic. + crate fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> Self { + debug!("Created new diagnostic"); + Self { + inner: DiagnosticBuilderInner { + state: DiagnosticBuilderState::Emittable(handler), + diagnostic: Box::new(diagnostic), + }, + _marker: PhantomData, + } + } +} + +// FIXME(eddyb) should there be a `Option` impl as well? +impl EmissionGuarantee for () { + fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self { + match db.inner.state { + // First `.emit()` call, the `&Handler` is still available. + DiagnosticBuilderState::Emittable(handler) => { + db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; + + handler.emit_diagnostic(&db.inner.diagnostic); + } + // `.emit()` was previously called, disallowed from repeating it. + DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {} + } + } +} + /// In general, the `DiagnosticBuilder` uses deref to allow access to /// the fields and methods of the embedded `diagnostic` in a /// transparent way. *However,* many of the methods are intended to @@ -83,52 +228,43 @@ macro_rules! forward { $(#[$attrs])* #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] pub fn $n(&mut self, $($name: $ty),*) -> &mut Self { - self.diagnostic.$n($($name),*); + self.inner.diagnostic.$n($($name),*); self } }; } -impl<'a> Deref for DiagnosticBuilder<'a> { +impl Deref for DiagnosticBuilder<'_, G> { type Target = Diagnostic; fn deref(&self) -> &Diagnostic { - &self.diagnostic + &self.inner.diagnostic } } -impl<'a> DerefMut for DiagnosticBuilder<'a> { +impl DerefMut for DiagnosticBuilder<'_, G> { fn deref_mut(&mut self) -> &mut Diagnostic { - &mut self.diagnostic + &mut self.inner.diagnostic } } -impl<'a> DiagnosticBuilder<'a> { +impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { /// Emit the diagnostic. - pub fn emit(&mut self) { - match self.state { - // First `.emit()` call, the `&Handler` is still available. - DiagnosticBuilderState::Emittable(handler) => { - handler.emit_diagnostic(&self); - self.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; - } - // `.emit()` was previously called, disallowed from repeating it. - DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => { - // FIXME(eddyb) rely on this to return a "proof" that an error - // was/will be emitted, despite doing no emission *here and now*. - } - } + #[track_caller] + pub fn emit(&mut self) -> G { + G::diagnostic_builder_emit_producing_guarantee(self) } /// Emit the diagnostic unless `delay` is true, /// in which case the emission will be delayed as a bug. /// /// See `emit` and `delay_as_bug` for details. - pub fn emit_unless(&mut self, delay: bool) { + #[track_caller] + pub fn emit_unless(&mut self, delay: bool) -> G { if delay { self.downgrade_to_delayed_bug(); } - self.emit(); + self.emit() } /// Cancel the diagnostic (a structured diagnostic must either be emitted or @@ -138,7 +274,7 @@ impl<'a> DiagnosticBuilder<'a> { /// which may be expected to *guarantee* the emission of an error, either /// at the time of the call, or through a prior `.emit()` call. pub fn cancel(mut self) { - self.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; + self.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; drop(self); } @@ -156,7 +292,7 @@ impl<'a> DiagnosticBuilder<'a> { /// Converts the builder to a `Diagnostic` for later emission, /// unless handler has disabled such buffering, or `.emit()` was called. pub fn into_diagnostic(mut self) -> Option<(Diagnostic, &'a Handler)> { - let handler = match self.state { + let handler = match self.inner.state { // No `.emit()` calls, the `&Handler` is still available. DiagnosticBuilderState::Emittable(handler) => handler, // `.emit()` was previously called, nothing we can do. @@ -172,7 +308,7 @@ impl<'a> DiagnosticBuilder<'a> { // Take the `Diagnostic` by replacing it with a dummy. let dummy = Diagnostic::new(Level::Allow, ""); - let diagnostic = std::mem::replace(&mut *self.diagnostic, dummy); + let diagnostic = std::mem::replace(&mut *self.inner.diagnostic, dummy); // Disable the ICE on `Drop`. self.cancel(); @@ -347,57 +483,27 @@ impl<'a> DiagnosticBuilder<'a> { forward!(pub fn set_primary_message(&mut self, msg: impl Into) -> &mut Self); forward!(pub fn set_span(&mut self, sp: impl Into) -> &mut Self); forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self); - - /// Convenience function for internal use, clients should use one of the - /// `struct_*` methods on [`Handler`]. - crate fn new(handler: &'a Handler, level: Level, message: &str) -> DiagnosticBuilder<'a> { - DiagnosticBuilder::new_with_code(handler, level, None, message) - } - - /// Convenience function for internal use, clients should use one of the - /// `struct_*` methods on [`Handler`]. - crate fn new_with_code( - handler: &'a Handler, - level: Level, - code: Option, - message: &str, - ) -> DiagnosticBuilder<'a> { - let diagnostic = Diagnostic::new_with_code(level, code, message); - DiagnosticBuilder::new_diagnostic(handler, diagnostic) - } - - /// Creates a new `DiagnosticBuilder` with an already constructed - /// diagnostic. - crate fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> DiagnosticBuilder<'a> { - debug!("Created new diagnostic"); - DiagnosticBuilder { - state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(diagnostic), - } - } } -impl<'a> Debug for DiagnosticBuilder<'a> { +impl Debug for DiagnosticBuilder<'_, G> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.diagnostic.fmt(f) + self.inner.diagnostic.fmt(f) } } /// Destructor bomb - a `DiagnosticBuilder` must be either emitted or cancelled /// or we emit a bug. -impl<'a> Drop for DiagnosticBuilder<'a> { +impl Drop for DiagnosticBuilderInner<'_> { fn drop(&mut self) { match self.state { // No `.emit()` or `.cancel()` calls. DiagnosticBuilderState::Emittable(handler) => { if !panicking() { - let mut db = DiagnosticBuilder::new( - handler, + handler.emit_diagnostic(&Diagnostic::new( Level::Bug, "the following error was constructed but not emitted", - ); - db.emit(); - handler.emit_diagnostic(&self); + )); + handler.emit_diagnostic(&self.diagnostic); panic!(); } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b92b1cac2e89c..463308c27b25a 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -9,6 +9,8 @@ #![feature(let_else)] #![feature(nll)] #![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))] +#![feature(adt_const_params)] +#![allow(incomplete_features)] #[macro_use] extern crate rustc_macros; @@ -52,7 +54,7 @@ mod snippet; mod styled_buffer; pub use snippet::Style; -pub type PResult<'a, T> = Result>; +pub type PResult<'a, T> = Result>; // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger. // (See also the comment on `DiagnosticBuilder`'s `diagnostic` field.) @@ -609,7 +611,7 @@ impl Handler { } /// Steal a previously stashed diagnostic with the given `Span` and `StashKey` as the key. - pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option> { + pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option> { self.inner .borrow_mut() .stashed_diagnostics @@ -627,7 +629,11 @@ impl Handler { /// Attempting to `.emit()` the builder will only emit if either: /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` - pub fn struct_span_warn(&self, span: impl Into, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_span_warn( + &self, + span: impl Into, + msg: &str, + ) -> DiagnosticBuilder<'_, ()> { let mut result = self.struct_warn(msg); result.set_span(span); result @@ -638,7 +644,7 @@ impl Handler { &self, span: impl Into, msg: &str, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'_, ()> { let mut result = self.struct_allow(msg); result.set_span(span); result @@ -651,7 +657,7 @@ impl Handler { span: impl Into, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'_, ()> { let mut result = self.struct_span_warn(span, msg); result.code(code); result @@ -662,17 +668,21 @@ impl Handler { /// Attempting to `.emit()` the builder will only emit if either: /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` - pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Warning, msg) } /// Construct a builder at the `Allow` level with the `msg`. - pub fn struct_allow(&self, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_allow(&self, msg: &str) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Allow, msg) } /// Construct a builder at the `Error` level at the given `span` and with the `msg`. - pub fn struct_span_err(&self, span: impl Into, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_span_err( + &self, + span: impl Into, + msg: &str, + ) -> DiagnosticBuilder<'_, ErrorReported> { let mut result = self.struct_err(msg); result.set_span(span); result @@ -684,7 +694,7 @@ impl Handler { span: impl Into, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'_, ErrorReported> { let mut result = self.struct_span_err(span, msg); result.code(code); result @@ -692,18 +702,22 @@ impl Handler { /// Construct a builder at the `Error` level with the `msg`. // FIXME: This method should be removed (every error should have an associated error code). - pub fn struct_err(&self, msg: &str) -> DiagnosticBuilder<'_> { - DiagnosticBuilder::new(self, Level::Error { lint: false }, msg) + pub fn struct_err(&self, msg: &str) -> DiagnosticBuilder<'_, ErrorReported> { + DiagnosticBuilder::new_guaranteeing_error::<{ Level::Error { lint: false } }>(self, msg) } /// This should only be used by `rustc_middle::lint::struct_lint_level`. Do not use it for hard errors. #[doc(hidden)] - pub fn struct_err_lint(&self, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_err_lint(&self, msg: &str) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Error { lint: true }, msg) } /// Construct a builder at the `Error` level with the `msg` and the `code`. - pub fn struct_err_with_code(&self, msg: &str, code: DiagnosticId) -> DiagnosticBuilder<'_> { + pub fn struct_err_with_code( + &self, + msg: &str, + code: DiagnosticId, + ) -> DiagnosticBuilder<'_, ErrorReported> { let mut result = self.struct_err(msg); result.code(code); result @@ -714,7 +728,7 @@ impl Handler { &self, span: impl Into, msg: &str, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'_, ErrorReported> { let mut result = self.struct_fatal(msg); result.set_span(span); result @@ -726,24 +740,24 @@ impl Handler { span: impl Into, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'_, ErrorReported> { let mut result = self.struct_span_fatal(span, msg); result.code(code); result } /// Construct a builder at the `Error` level with the `msg`. - pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_> { - DiagnosticBuilder::new(self, Level::Fatal, msg) + pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_, ErrorReported> { + DiagnosticBuilder::new_guaranteeing_error::<{ Level::Fatal }>(self, msg) } /// Construct a builder at the `Help` level with the `msg`. - pub fn struct_help(&self, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_help(&self, msg: &str) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Help, msg) } /// Construct a builder at the `Note` level with the `msg`. - pub fn struct_note_without_error(&self, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_note_without_error(&self, msg: &str) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Note, msg) } @@ -804,7 +818,7 @@ impl Handler { self.emit_diag_at_span(Diagnostic::new(Note, msg), span); } - pub fn span_note_diag(&self, span: Span, msg: &str) -> DiagnosticBuilder<'_> { + pub fn span_note_diag(&self, span: Span, msg: &str) -> DiagnosticBuilder<'_, ()> { let mut db = DiagnosticBuilder::new(self, Note, msg); db.set_span(span); db @@ -1222,7 +1236,7 @@ impl DelayedDiagnostic { } } -#[derive(Copy, PartialEq, Clone, Hash, Debug, Encodable, Decodable)] +#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug, Encodable, Decodable)] pub enum Level { Bug, DelayedBug, diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 2bdf3b3912619..4e951ad9d4b6d 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -10,7 +10,7 @@ use rustc_ast::{self as ast, AstLike, Attribute, Item, NodeId, PatKind}; use rustc_attr::{self as attr, Deprecation, Stability}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{self, Lrc}; -use rustc_errors::{Applicability, DiagnosticBuilder, ErrorReported}; +use rustc_errors::{Applicability, DiagnosticBuilder, ErrorReported, PResult}; use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT; use rustc_lint_defs::BuiltinLintDiagnostics; use rustc_parse::{self, nt_to_tokenstream, parser, MACRO_ARGUMENTS}; @@ -1072,7 +1072,11 @@ impl<'a> ExtCtxt<'a> { self.current_expansion.id.expansion_cause() } - pub fn struct_span_err>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_span_err>( + &self, + sp: S, + msg: &str, + ) -> DiagnosticBuilder<'a, ErrorReported> { self.sess.parse_sess.span_diagnostic.struct_span_err(sp, msg) } @@ -1130,11 +1134,7 @@ impl<'a> ExtCtxt<'a> { /// This unifies the logic used for resolving `include_X!`. /// /// FIXME: move this to `rustc_builtin_macros` and make it private. - pub fn resolve_path( - &self, - path: impl Into, - span: Span, - ) -> Result> { + pub fn resolve_path(&self, path: impl Into, span: Span) -> PResult<'a, PathBuf> { let path = path.into(); // Relative paths are resolved relative to the file in which they are found @@ -1174,7 +1174,7 @@ pub fn expr_to_spanned_string<'a>( cx: &'a mut ExtCtxt<'_>, expr: P, err_msg: &str, -) -> Result<(Symbol, ast::StrStyle, Span), Option<(DiagnosticBuilder<'a>, bool)>> { +) -> Result<(Symbol, ast::StrStyle, Span), Option<(DiagnosticBuilder<'a, ErrorReported>, bool)>> { // Perform eager expansion on the expression. // We want to be able to handle e.g., `concat!("foo", "bar")`. let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr(); @@ -1233,7 +1233,9 @@ pub fn check_zero_tts(cx: &ExtCtxt<'_>, sp: Span, tts: TokenStream, name: &str) pub fn parse_expr(p: &mut parser::Parser<'_>) -> Option> { match p.parse_expr() { Ok(e) => return Some(e), - Err(mut err) => err.emit(), + Err(mut err) => { + err.emit(); + } } while p.token != token::Eof { p.bump(); diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 37e9f6adf0db8..4af7d2b7ec6fd 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -62,7 +62,7 @@ crate fn annotate_err_with_kind(err: &mut Diagnostic, kind: AstFragmentKind, spa } fn emit_frag_parse_err( - mut e: DiagnosticBuilder<'_>, + mut e: DiagnosticBuilder<'_, rustc_errors::ErrorReported>, parser: &Parser<'_>, orig_parser: &mut Parser<'_>, site_span: Span, diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index aa54bdbd3a73d..1ce3766579bd9 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -1,7 +1,7 @@ use crate::base::ModuleData; use rustc_ast::ptr::P; use rustc_ast::{token, Attribute, Inline, Item}; -use rustc_errors::{struct_span_err, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorReported}; use rustc_parse::new_parser_from_file; use rustc_parse::validate_attr; use rustc_session::parse::ParseSess; @@ -39,7 +39,7 @@ pub enum ModError<'a> { ModInBlock(Option), FileNotFound(Ident, PathBuf, PathBuf), MultipleCandidates(Ident, PathBuf, PathBuf), - ParserError(DiagnosticBuilder<'a>), + ParserError(DiagnosticBuilder<'a, ErrorReported>), } crate fn parse_external_mod( @@ -242,7 +242,7 @@ pub fn default_submod_path<'a>( } impl ModError<'_> { - fn report(self, sess: &Session, span: Span) { + fn report(self, sess: &Session, span: Span) -> ErrorReported { let diag = &sess.parse_sess.span_diagnostic; match self { ModError::CircularInclusion(file_paths) => { diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 99a945b1c913b..869cada400f0f 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -446,7 +446,9 @@ impl server::TokenStream for Rustc<'_, '_> { } expr }; - let expr = expr.map_err(|mut err| err.emit())?; + let expr = expr.map_err(|mut err| { + err.emit(); + })?; // Perform eager expansion on the expression. let expr = self diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index cbf28d48e1431..9da287c959a44 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -58,7 +58,7 @@ use crate::traits::{ }; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, struct_span_err, Diagnostic}; +use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorReported}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -230,7 +230,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( span: Span, hidden_ty: Ty<'tcx>, hidden_region: ty::Region<'tcx>, -) -> DiagnosticBuilder<'tcx> { +) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = struct_span_err!( tcx.sess, span, @@ -2014,7 +2014,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { &self, trace: TypeTrace<'tcx>, terr: &TypeError<'tcx>, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { use crate::traits::ObligationCauseCode::MatchExpressionArm; debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr); @@ -2222,7 +2222,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { origin: Option>, bound_kind: GenericKind<'tcx>, sub: Region<'tcx>, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'a, ErrorReported> { let hir = self.tcx.hir(); // Attempt to obtain the span of the parameter so we can // suggest adding an explicit lifetime bound to it. @@ -2648,7 +2648,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { fn report_inference_failure( &self, var_origin: RegionVariableOrigin, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let br_string = |br: ty::BoundRegionKind| { let mut s = match br { ty::BrNamed(_, name) => name.to_string(), diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 88a65fbb4e613..8876c3ecd540d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -1,6 +1,8 @@ use crate::infer::type_variable::TypeVariableOriginKind; use crate::infer::{InferCtxt, Symbol}; -use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{ + pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported, +}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::DefId; @@ -491,7 +493,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { arg: GenericArg<'tcx>, impl_candidates: Vec>, error_code: TypeAnnotationNeeded, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let arg = self.resolve_vars_if_possible(arg); let arg_data = self.extract_inference_diagnostics_data(arg, None); @@ -918,7 +920,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { kind: hir::GeneratorKind, span: Span, ty: Ty<'tcx>, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let ty = self.resolve_vars_if_possible(ty); let data = self.extract_inference_diagnostics_data(ty.into(), None); 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 f44e6e04346b2..a8b878ae344a2 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 @@ -46,7 +46,7 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> { self.infcx.tcx } - pub fn try_report_from_nll(&self) -> Option> { + pub fn try_report_from_nll(&self) -> Option> { // Due to the improved diagnostics returned by the MIR borrow checker, only a subset of // the nice region errors are required when running under the MIR borrow checker. self.try_report_named_anon_conflict().or_else(|| self.try_report_placeholder_conflict()) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 17ff5d45c89f9..825aadaad9a0c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -2,13 +2,15 @@ //! where one region is named and the other is anonymous. use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type; use crate::infer::error_reporting::nice_region_error::NiceRegionError; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported}; use rustc_middle::ty; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// When given a `ConcreteFailure` for a function with parameters containing a named region and /// an anonymous region, emit an descriptive diagnostic error. - pub(super) fn try_report_named_anon_conflict(&self) -> Option> { + pub(super) fn try_report_named_anon_conflict( + &self, + ) -> Option> { let (span, sub, sup) = self.regions()?; debug!( diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index 0be7a67a1b8e0..8b786e6e85aaf 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -4,7 +4,7 @@ use crate::infer::ValuePairs; use crate::infer::{SubregionOrigin, TypeTrace}; use crate::traits::{ObligationCause, ObligationCauseCode}; use rustc_data_structures::intern::Interned; -use rustc_errors::{Diagnostic, DiagnosticBuilder}; +use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorReported}; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefId; use rustc_middle::ty::error::ExpectedFound; @@ -17,7 +17,9 @@ use std::fmt::{self, Write}; impl<'tcx> NiceRegionError<'_, 'tcx> { /// When given a `ConcreteFailure` for a function with arguments containing a named region and /// an anonymous region, emit a descriptive diagnostic error. - pub(super) fn try_report_placeholder_conflict(&self) -> Option> { + pub(super) fn try_report_placeholder_conflict( + &self, + ) -> Option> { match &self.error { /////////////////////////////////////////////////////////////////////////// // NB. The ordering of cases in this match is very @@ -153,7 +155,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { sub_placeholder: Option>, sup_placeholder: Option>, value_pairs: &ValuePairs<'tcx>, - ) -> Option> { + ) -> Option> { let (expected_substs, found_substs, trait_def_id) = match value_pairs { ValuePairs::TraitRefs(ExpectedFound { expected, found }) if expected.def_id == found.def_id => @@ -201,7 +203,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { trait_def_id: DefId, expected_substs: SubstsRef<'tcx>, actual_substs: SubstsRef<'tcx>, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let span = cause.span(self.tcx()); let msg = format!( "implementation of `{}` is not general enough", diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index f44dbef46b8c3..5dc8c89460856 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -1,6 +1,6 @@ use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt}; use crate::infer::{self, InferCtxt, SubregionOrigin}; -use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, ErrorReported}; use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{self, Region}; @@ -109,7 +109,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx>, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { match origin { infer::Subtype(box trace) => { let terr = TypeError::RegionsDoesNotOutlive(sup, sub); @@ -401,7 +401,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { placeholder_origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx>, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { // I can't think how to do better than this right now. -nikomatsakis debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure"); match placeholder_origin { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index fc54d04d0f92b..95608f413d538 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -14,7 +14,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::undo_log::Rollback; use rustc_data_structures::unify as ut; -use rustc_errors::DiagnosticBuilder; +use rustc_errors::{DiagnosticBuilder, ErrorReported}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues}; @@ -1475,9 +1475,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { sp: Span, mk_diag: M, actual_ty: Ty<'tcx>, - ) -> DiagnosticBuilder<'tcx> + ) -> DiagnosticBuilder<'tcx, ErrorReported> where - M: FnOnce(String) -> DiagnosticBuilder<'tcx>, + M: FnOnce(String) -> DiagnosticBuilder<'tcx, ErrorReported>, { let actual_ty = self.resolve_vars_if_possible(actual_ty); debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty); @@ -1498,7 +1498,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { expected: Ty<'tcx>, actual: Ty<'tcx>, err: TypeError<'tcx>, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let trace = TypeTrace::types(cause, true, expected, actual); self.report_and_explain_type_error(trace, &err) } @@ -1509,7 +1509,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { expected: ty::Const<'tcx>, actual: ty::Const<'tcx>, err: TypeError<'tcx>, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let trace = TypeTrace::consts(cause, true, expected, actual); self.report_and_explain_type_error(trace, &err) } diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index 1a5ffd93701c6..35430849290e7 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -2,7 +2,7 @@ use super::ObjectSafetyViolation; use crate::infer::InferCtxt; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{struct_span_err, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorReported}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::TyCtxt; @@ -17,7 +17,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { impl_item_def_id: DefId, trait_item_def_id: DefId, requirement: &dyn fmt::Display, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let msg = "impl has stricter requirements than trait"; let sp = self.tcx.sess.source_map().guess_head_span(error_span); @@ -40,7 +40,7 @@ pub fn report_object_safety_error<'tcx>( span: Span, trait_def_id: DefId, violations: &[ObjectSafetyViolation], -) -> DiagnosticBuilder<'tcx> { +) -> DiagnosticBuilder<'tcx, ErrorReported> { let trait_str = tcx.def_path_str(trait_def_id); let trait_span = tcx.hir().get_if_local(trait_def_id).and_then(|node| match node { hir::Node::Item(item) => Some(item.ident.span), diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index d8f55292ccd8d..c93028d621ed7 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -319,7 +319,7 @@ impl LintStore { ) { let (tool_name, lint_name_only) = parse_lint_and_tool_name(lint_name); if lint_name_only == crate::WARNINGS.name_lower() && level == Level::ForceWarn { - return struct_span_err!( + struct_span_err!( sess, DUMMY_SP, E0602, @@ -327,6 +327,7 @@ impl LintStore { crate::WARNINGS.name_lower() ) .emit(); + return; } let db = match self.check_lint_name(lint_name_only, tool_name, registered_tools) { CheckLintNameResult::Ok(_) => None, @@ -339,7 +340,7 @@ impl LintStore { err.help(&format!("did you mean: `{}`", suggestion)); } - Some(err) + Some(err.forget_guarantee()) } CheckLintNameResult::Tool(result) => match result { Err((Some(_), new_name)) => Some(sess.struct_warn(&format!( @@ -350,13 +351,16 @@ impl LintStore { ))), _ => None, }, - CheckLintNameResult::NoTool => Some(struct_span_err!( - sess, - DUMMY_SP, - E0602, - "unknown lint tool: `{}`", - tool_name.unwrap() - )), + CheckLintNameResult::NoTool => Some( + struct_span_err!( + sess, + DUMMY_SP, + E0602, + "unknown lint tool: `{}`", + tool_name.unwrap() + ) + .forget_guarantee(), + ), }; if let Some(mut db) = db { diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 35c7d885e1d74..d7cdb08d81714 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -3,7 +3,7 @@ use crate::late::unerased_lint_store; use rustc_ast as ast; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, Diagnostic}; use rustc_hir as hir; use rustc_hir::{intravisit, HirId}; use rustc_middle::hir::nested_filter; @@ -150,29 +150,28 @@ impl<'s> LintLevelsBuilder<'s> { fcw_warning, specs, old_src, id_name ); - let decorate_diag_builder = |mut diag_builder: DiagnosticBuilder<'_>| { - diag_builder.span_label(src.span(), "overruled by previous forbid"); + let decorate_diag = |diag: &mut Diagnostic| { + diag.span_label(src.span(), "overruled by previous forbid"); match old_src { LintLevelSource::Default => { - diag_builder.note(&format!( + diag.note(&format!( "`forbid` lint level is the default for {}", id.to_string() )); } LintLevelSource::Node(_, forbid_source_span, reason) => { - diag_builder.span_label(forbid_source_span, "`forbid` level set here"); + diag.span_label(forbid_source_span, "`forbid` level set here"); if let Some(rationale) = reason { - diag_builder.note(rationale.as_str()); + diag.note(rationale.as_str()); } } LintLevelSource::CommandLine(_, _) => { - diag_builder.note("`forbid` lint level was set on command line"); + diag.note("`forbid` lint level was set on command line"); } } - diag_builder.emit(); }; if !fcw_warning { - let diag_builder = struct_span_err!( + let mut diag_builder = struct_span_err!( self.sess, src.span(), E0453, @@ -180,18 +179,20 @@ impl<'s> LintLevelsBuilder<'s> { level.as_str(), src.name(), ); - decorate_diag_builder(diag_builder); + decorate_diag(&mut diag_builder); + diag_builder.emit(); } else { self.struct_lint( FORBIDDEN_LINT_GROUPS, Some(src.span().into()), |diag_builder| { - let diag_builder = diag_builder.build(&format!( + let mut diag_builder = diag_builder.build(&format!( "{}({}) incompatible with previous forbid", level.as_str(), src.name(), )); - decorate_diag_builder(diag_builder); + decorate_diag(&mut diag_builder); + diag_builder.emit(); }, ); } diff --git a/compiler/rustc_macros/src/session_diagnostic.rs b/compiler/rustc_macros/src/session_diagnostic.rs index 80dcf99da6224..9a7784ca72fc6 100644 --- a/compiler/rustc_macros/src/session_diagnostic.rs +++ b/compiler/rustc_macros/src/session_diagnostic.rs @@ -232,7 +232,7 @@ impl<'a> SessionDiagnosticDerive<'a> { fn into_diagnostic( self, #sess: &'__session_diagnostic_sess rustc_session::Session - ) -> rustc_errors::DiagnosticBuilder<'__session_diagnostic_sess> { + ) -> rustc_errors::DiagnosticBuilder<'__session_diagnostic_sess, rustc_errors::ErrorReported> { #implementation } } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 0f10c269a04a3..dce1b35c6b889 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -243,7 +243,9 @@ impl Collector<'_> { if matches!(lib.kind, NativeLibKind::Framework { .. }) && !is_osx { let msg = "native frameworks are only available on macOS targets"; match span { - Some(span) => struct_span_err!(self.tcx.sess, span, E0455, "{}", msg).emit(), + Some(span) => { + struct_span_err!(self.tcx.sess, span, E0455, "{}", msg).emit(); + } None => self.tcx.sess.err(msg), } } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 8e28ae3ce44c4..35e1558600d5b 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -186,18 +186,18 @@ impl<'a> HashStable> for LintLevelMap { } } -pub struct LintDiagnosticBuilder<'a>(DiagnosticBuilder<'a>); +pub struct LintDiagnosticBuilder<'a>(DiagnosticBuilder<'a, ()>); impl<'a> LintDiagnosticBuilder<'a> { /// Return the inner DiagnosticBuilder, first setting the primary message to `msg`. - pub fn build(mut self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn build(mut self, msg: &str) -> DiagnosticBuilder<'a, ()> { 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> { + pub fn new(err: DiagnosticBuilder<'a, ()>) -> LintDiagnosticBuilder<'a> { LintDiagnosticBuilder(err) } } diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index c5866924eda43..31468ce73bfc5 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -36,7 +36,10 @@ TrivialTypeFoldableAndLiftImpls! { pub type EvalToAllocationRawResult<'tcx> = Result, ErrorHandled>; pub type EvalToConstValueResult<'tcx> = Result, ErrorHandled>; -pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'tcx> { +pub fn struct_error<'tcx>( + tcx: TyCtxtAt<'tcx>, + msg: &str, +) -> DiagnosticBuilder<'tcx, ErrorReported> { struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg) } diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index a2d0fb36eb243..2663ed9049da9 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -6,7 +6,9 @@ use super::{PatCtxt, PatternError}; use rustc_arena::TypedArena; use rustc_ast::Mutability; -use rustc_errors::{error_code, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{ + error_code, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported, +}; use rustc_hir as hir; use rustc_hir::def::*; use rustc_hir::def_id::DefId; @@ -36,7 +38,11 @@ crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) { visitor.visit_body(tcx.hir().body(body_id)); } -fn create_e0004(sess: &Session, sp: Span, error_message: String) -> DiagnosticBuilder<'_> { +fn create_e0004( + sess: &Session, + sp: Span, + error_message: String, +) -> DiagnosticBuilder<'_, ErrorReported> { struct_span_err!(sess, sp, E0004, "{}", &error_message) } 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 a19a3c8b1d506..8731669b10958 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 diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 4cdd83c0acd3c..3212fc39fb9c2 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -3,7 +3,9 @@ use rustc_ast::ast::{self, AttrStyle}; use rustc_ast::token::{self, CommentKind, Token, TokenKind}; use rustc_ast::tokenstream::{Spacing, TokenStream}; use rustc_ast::util::unicode::contains_text_flow_control_chars; -use rustc_errors::{error_code, Applicability, DiagnosticBuilder, FatalError, PResult}; +use rustc_errors::{ + error_code, Applicability, DiagnosticBuilder, ErrorReported, FatalError, PResult, +}; use rustc_lexer::unescape::{self, Mode}; use rustc_lexer::{Base, DocStyle, RawStrError}; use rustc_session::lint::builtin::{ @@ -127,7 +129,7 @@ impl<'a> StringReader<'a> { to_pos: BytePos, m: &str, c: char, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'a, ErrorReported> { self.sess .span_diagnostic .struct_span_fatal(self.mk_sp(from_pos, to_pos), &format!("{}: {}", m, escaped_char(c))) diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index a41956c58f005..c7d166319eac8 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -144,7 +144,7 @@ pub(crate) fn emit_unescape_error( c.escape_default().to_string(), Applicability::MachineApplicable, ) - .emit() + .emit(); } EscapeError::BareCarriageReturn => { let msg = if mode.in_double_quotes() { @@ -292,16 +292,18 @@ pub(crate) fn emit_unescape_error( .span_label(span, "must have at most 6 hex digits") .emit(); } - EscapeError::UnclosedUnicodeEscape => handler - .struct_span_err(span, "unterminated unicode escape") - .span_label(span, "missing a closing `}`") - .span_suggestion_verbose( - span.shrink_to_hi(), - "terminate the unicode escape", - "}".to_string(), - Applicability::MaybeIncorrect, - ) - .emit(), + EscapeError::UnclosedUnicodeEscape => { + handler + .struct_span_err(span, "unterminated unicode escape") + .span_label(span, "missing a closing `}`") + .span_suggestion_verbose( + span.shrink_to_hi(), + "terminate the unicode escape", + "}".to_string(), + Applicability::MaybeIncorrect, + ) + .emit(); + } EscapeError::NoBraceInUnicodeEscape => { let msg = "incorrect unicode escape sequence"; let mut diag = handler.struct_span_err(span, msg); @@ -347,7 +349,7 @@ pub(crate) fn emit_unescape_error( } EscapeError::ZeroChars => { let msg = "empty character literal"; - handler.struct_span_err(span, msg).span_label(span, msg).emit() + handler.struct_span_err(span, msg).span_label(span, msg).emit(); } EscapeError::LoneSlash => { let msg = "invalid trailing slash in literal"; diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index d56d3124a5652..f1c2dcf10e869 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -16,7 +16,7 @@ use rustc_ast::{ }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{pluralize, struct_span_err, Diagnostic}; +use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorReported}; use rustc_errors::{Applicability, DiagnosticBuilder, Handler, PResult}; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, Ident}; @@ -53,7 +53,11 @@ pub enum Error { } impl Error { - fn span_err(self, sp: impl Into, handler: &Handler) -> DiagnosticBuilder<'_> { + fn span_err( + self, + sp: impl Into, + handler: &Handler, + ) -> DiagnosticBuilder<'_, ErrorReported> { match self { Error::UselessDocComment => { let mut err = struct_span_err!( @@ -151,11 +155,19 @@ impl AttemptLocalParseRecovery { } impl<'a> Parser<'a> { - pub(super) fn span_err>(&self, sp: S, err: Error) -> DiagnosticBuilder<'a> { + pub(super) fn span_err>( + &self, + sp: S, + err: Error, + ) -> DiagnosticBuilder<'a, ErrorReported> { err.span_err(sp, self.diagnostic()) } - pub fn struct_span_err>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> { + pub fn struct_span_err>( + &self, + sp: S, + m: &str, + ) -> DiagnosticBuilder<'a, ErrorReported> { self.sess.span_diagnostic.struct_span_err(sp, m) } @@ -171,7 +183,7 @@ impl<'a> Parser<'a> { self.sess.source_map().span_to_snippet(span) } - pub(super) fn expected_ident_found(&self) -> DiagnosticBuilder<'a> { + pub(super) fn expected_ident_found(&self) -> DiagnosticBuilder<'a, ErrorReported> { let mut err = self.struct_span_err( self.token.span, &format!("expected identifier, found {}", super::token_descr(&self.token)), @@ -717,7 +729,7 @@ impl<'a> Parser<'a> { /// encounter a parse error when encountering the first `,`. pub(super) fn check_mistyped_turbofish_with_multiple_type_params( &mut self, - mut e: DiagnosticBuilder<'a>, + mut e: DiagnosticBuilder<'a, ErrorReported>, expr: &mut P, ) -> PResult<'a, ()> { if let ExprKind::Binary(binop, _, _) = &expr.kind { @@ -1439,7 +1451,7 @@ impl<'a> Parser<'a> { pub(super) fn recover_closing_delimiter( &mut self, tokens: &[TokenKind], - mut err: DiagnosticBuilder<'a>, + mut err: DiagnosticBuilder<'a, ErrorReported>, ) -> PResult<'a, bool> { let mut pos = None; // We want to use the last closing delim that would apply. @@ -1810,7 +1822,7 @@ impl<'a> Parser<'a> { } } - pub(super) fn expected_expression_found(&self) -> DiagnosticBuilder<'a> { + pub(super) fn expected_expression_found(&self) -> DiagnosticBuilder<'a, ErrorReported> { let (span, msg) = match (&self.token.kind, self.subparser_name) { (&token::Eof, Some(origin)) => { let sp = self.sess.source_map().next_point(self.prev_token.span); @@ -2016,7 +2028,7 @@ impl<'a> Parser<'a> { pub fn recover_const_arg( &mut self, start: Span, - mut err: DiagnosticBuilder<'a>, + mut err: DiagnosticBuilder<'a, ErrorReported>, ) -> PResult<'a, GenericArg> { let is_op = AssocOp::from_token(&self.token) .and_then(|op| { @@ -2096,7 +2108,7 @@ impl<'a> Parser<'a> { pub(super) fn incorrect_move_async_order_found( &self, move_async_span: Span, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'a, ErrorReported> { let mut err = self.struct_span_err(move_async_span, "the order of `move` and `async` is incorrect"); err.span_suggestion_verbose( diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index a66307bcbe04d..c6919779ffd35 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -17,7 +17,7 @@ use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, Lit, UnOp use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind}; use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits}; use rustc_ast_pretty::pprust; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, PResult}; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported, PResult}; use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP; use rustc_session::lint::BuiltinLintDiagnostics; use rustc_span::edition::LATEST_STABLE_EDITION; @@ -1167,7 +1167,9 @@ impl<'a> Parser<'a> { return Some(self.mk_expr_err(span)); } Ok(_) => {} - Err(mut err) => err.emit(), + Err(mut err) => { + err.emit(); + } } } _ => {} @@ -1819,6 +1821,7 @@ impl<'a> Parser<'a> { err } else { self.struct_span_err(sp, &format!("suffixes on {} are invalid", kind)) + .forget_guarantee() }; err.span_label(sp, format!("invalid suffix `{}`", suf)); err.emit(); @@ -2100,9 +2103,9 @@ impl<'a> Parser<'a> { fn error_missing_if_then_block( &self, if_span: Span, - err: Option>, + err: Option>, binop_span: Option, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'a, ErrorReported> { let msg = "this `if` expression has a condition, but no block"; let mut err = if let Some(mut err) = err { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 1fd8472f3806f..bd349e89482ef 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -13,7 +13,7 @@ use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, Vari use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind}; use rustc_ast::{MacArgs, MacCall, MacDelimiter}; use rustc_ast_pretty::pprust; -use rustc_errors::{struct_span_err, Applicability, PResult, StashKey}; +use rustc_errors::{struct_span_err, Applicability, ErrorReported, PResult, StashKey}; use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; use rustc_span::lev_distance::lev_distance; use rustc_span::source_map::{self, Span}; @@ -801,7 +801,7 @@ impl<'a> Parser<'a> { before_where_clause_span: Span, after_predicates: &[WherePredicate], after_where_clause_span: Span, - ) { + ) -> ErrorReported { let mut err = self.struct_span_err(after_where_clause_span, "where clause not allowed here"); if !after_predicates.is_empty() { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index b30705d8d758c..d8e6d5037bbd8 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -32,7 +32,7 @@ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use rustc_errors::PResult; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported, FatalError}; use rustc_session::parse::ParseSess; use rustc_span::source_map::{MultiSpan, Span, DUMMY_SP}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -877,7 +877,7 @@ impl<'a> Parser<'a> { fn recover_missing_braces_around_closure_body( &mut self, closure_spans: ClosureSpans, - mut expect_err: DiagnosticBuilder<'_>, + mut expect_err: DiagnosticBuilder<'_, ErrorReported>, ) -> PResult<'a, ()> { let initial_semicolon = self.token.span; @@ -1429,7 +1429,7 @@ impl<'a> Parser<'a> { crate fn make_unclosed_delims_error( unmatched: UnmatchedBrace, sess: &ParseSess, -) -> Option> { +) -> Option> { // `None` here means an `Eof` was found. We already emit those errors elsewhere, we add them to // `unmatched_braces` only for error recovery in the `Parser`. let found_delim = unmatched.found_delim?; diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 986a8c2b47d42..d41298711459f 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -8,7 +8,7 @@ use rustc_ast::{ PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax, }; use rustc_ast_pretty::pprust; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported, PResult}; use rustc_span::source_map::{respan, Span, Spanned}; use rustc_span::symbol::{kw, sym, Ident}; @@ -655,7 +655,7 @@ impl<'a> Parser<'a> { fn fatal_unexpected_non_pat( &mut self, - err: DiagnosticBuilder<'a>, + err: DiagnosticBuilder<'a, ErrorReported>, expected: Expected, ) -> PResult<'a, P> { err.cancel(); @@ -886,7 +886,7 @@ impl<'a> Parser<'a> { let mut fields = Vec::new(); let mut etc = false; let mut ate_comma = true; - let mut delayed_err: Option> = None; + let mut delayed_err: Option> = None; let mut etc_span = None; while self.token != token::CloseDelim(token::Brace) { diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index bbd24289b15cd..6b195285243fd 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -18,7 +18,7 @@ use rustc_ast::{ }; use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt}; use rustc_ast::{StmtKind, DUMMY_NODE_ID}; -use rustc_errors::{Applicability, DiagnosticBuilder, PResult}; +use rustc_errors::{Applicability, DiagnosticBuilder, ErrorReported, PResult}; use rustc_span::source_map::{BytePos, Span}; use rustc_span::symbol::{kw, sym}; @@ -414,7 +414,10 @@ impl<'a> Parser<'a> { Ok(block) } - fn error_block_no_opening_brace_msg(&mut self, msg: &str) -> DiagnosticBuilder<'a> { + fn error_block_no_opening_brace_msg( + &mut self, + msg: &str, + ) -> DiagnosticBuilder<'a, ErrorReported> { let sp = self.token.span; let mut e = self.struct_span_err(sp, msg); let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon; diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 566b77a5e9e55..0b01f9e927f33 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -345,7 +345,8 @@ impl<'a> Parser<'a> { let lt_no_plus = self.check_lifetime() && !self.look_ahead(1, |t| t.is_like_plus()); let bounds = self.parse_generic_bounds_common(allow_plus, None)?; if lt_no_plus { - self.struct_span_err(lo, "lifetime in trait object type must be followed by `+`").emit() + self.struct_span_err(lo, "lifetime in trait object type must be followed by `+`") + .emit(); } Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None)) } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3d69e8ba4e430..0786a42fc113a 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2095,7 +2095,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { rustc_errors::Applicability::MachineApplicable, ); } - err.emit() + err.emit(); } } } diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 2b11f6b0c1d02..0fdbdb7b08d00 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -219,7 +219,9 @@ impl<'tcx> CheckConstVisitor<'tcx> { required_gates.iter().copied().filter(|&g| !features.enabled(g)).collect(); match missing_gates.as_slice() { - [] => struct_span_err!(tcx.sess, span, E0744, "{}", msg).emit(), + [] => { + struct_span_err!(tcx.sess, span, E0744, "{}", msg).emit(); + } [missing_primary, ref missing_secondary @ ..] => { let mut err = feature_err(&tcx.sess.parse_sess, *missing_primary, span, &msg); diff --git a/compiler/rustc_passes/src/intrinsicck.rs b/compiler/rustc_passes/src/intrinsicck.rs index d7dde157864a4..b2129ce9f24fc 100644 --- a/compiler/rustc_passes/src/intrinsicck.rs +++ b/compiler/rustc_passes/src/intrinsicck.rs @@ -118,7 +118,7 @@ impl<'tcx> ExprVisitor<'tcx> { err.note(&format!("source type: `{}` ({})", from, skeleton_string(from, sk_from))) .note(&format!("target type: `{}` ({})", to, skeleton_string(to, sk_to))); } - err.emit() + err.emit(); } fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool { diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index b1ff1e15a9db5..91b6ea0383507 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -7,7 +7,7 @@ use crate::query::caches::QueryCache; use crate::query::{QueryCacheStore, QueryContext, QueryState}; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_errors::DiagnosticBuilder; +use rustc_errors::{DiagnosticBuilder, ErrorReported}; use std::fmt::Debug; use std::hash::Hash; @@ -27,7 +27,7 @@ pub struct QueryVtable { pub compute: fn(CTX::DepContext, K) -> V, pub hash_result: Option, &V) -> Fingerprint>, - pub handle_cycle_error: fn(CTX, DiagnosticBuilder<'_>) -> V, + pub handle_cycle_error: fn(CTX, DiagnosticBuilder<'_, ErrorReported>) -> V, pub try_load_from_disk: Option Option>, } diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 4588403925efd..260fc3bff4471 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -4,7 +4,7 @@ use crate::query::{QueryContext, QueryStackFrame}; use rustc_hir::def::DefKind; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, Handler, Level}; +use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, ErrorReported, Handler, Level}; use rustc_session::Session; use rustc_span::Span; @@ -530,7 +530,7 @@ pub fn deadlock(tcx: CTX, registry: &rayon_core::Registry) { pub(crate) fn report_cycle<'a>( sess: &'a Session, CycleError { usage, cycle: stack }: CycleError, -) -> DiagnosticBuilder<'a> { +) -> DiagnosticBuilder<'a, ErrorReported> { assert!(!stack.is_empty()); let fix_span = |span: Span, query: &QueryStackFrame| { diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 77e1fd3f2ccbb..23df0d4dcd439 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -14,7 +14,7 @@ use rustc_data_structures::profiling::TimingGuard; use rustc_data_structures::sharded::{get_shard_index_by_hash, Sharded}; use rustc_data_structures::sync::{Lock, LockGuard}; use rustc_data_structures::thin_vec::ThinVec; -use rustc_errors::{DiagnosticBuilder, FatalError}; +use rustc_errors::{DiagnosticBuilder, ErrorReported, FatalError}; use rustc_session::Session; use rustc_span::{Span, DUMMY_SP}; use std::cell::Cell; @@ -143,7 +143,7 @@ where fn mk_cycle( tcx: CTX, error: CycleError, - handle_cycle_error: fn(CTX, DiagnosticBuilder<'_>) -> V, + handle_cycle_error: fn(CTX, DiagnosticBuilder<'_, ErrorReported>) -> V, cache: &dyn crate::query::QueryStorage, ) -> R where diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 3fa9343c399ad..6a3d998a25838 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1068,8 +1068,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { .emit(); } } - let ill_formed = - |span| struct_span_err!(self.r.session, span, E0466, "bad macro import").emit(); + let ill_formed = |span| { + struct_span_err!(self.r.session, span, E0466, "bad macro import").emit(); + }; match attr.meta() { Some(meta) => match meta.kind { MetaItemKind::Word => { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index a1d4758c8ed25..b366473cb30c0 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -3,7 +3,7 @@ use std::ptr; use rustc_ast::{self as ast, Path}; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{struct_span_err, Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported}; use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind}; @@ -110,7 +110,7 @@ impl<'a> Resolver<'a> { &self, span: Span, resolution_error: ResolutionError<'_>, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'_, ErrorReported> { match resolution_error { ResolutionError::GenericParamsFromOuterFunction(outer_res, has_generic_params) => { let mut err = struct_span_err!( @@ -624,7 +624,10 @@ impl<'a> Resolver<'a> { } } - crate fn report_vis_error(&self, vis_resolution_error: VisResolutionError<'_>) { + crate fn report_vis_error( + &self, + vis_resolution_error: VisResolutionError<'_>, + ) -> ErrorReported { match vis_resolution_error { VisResolutionError::Relative2018(span, path) => { let mut err = self.session.struct_span_err( diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 70be891aecc9a..b71776c161531 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -12,7 +12,9 @@ use rustc_ast::{ }; use rustc_ast_pretty::pprust::path_segment_to_string; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{ + pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported, +}; use rustc_hir as hir; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind}; @@ -133,7 +135,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { span: Span, source: PathSource<'_>, res: Option, - ) -> (DiagnosticBuilder<'a>, Vec) { + ) -> (DiagnosticBuilder<'a, ErrorReported>, Vec) { let ident_span = path.last().map_or(span, |ident| ident.ident.span); let ns = source.namespace(); let is_expected = &|res| source.is_expected(res); @@ -1817,7 +1819,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { &self, spans: Vec, count: usize, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { struct_span_err!( self.tcx.sess, spans, diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 206da43ffd459..23a8189f62fd8 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1572,6 +1572,7 @@ fn signal_shadowing_problem(tcx: TyCtxt<'_>, name: Symbol, orig: Original, shado name, orig.kind.desc() ) + .forget_guarantee() } else { // shadowing involving a label is only a warning, due to issues with // labels and lifetimes not being macro-hygienic. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ca6451b856da6..65431d27638c0 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -40,7 +40,7 @@ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; -use rustc_errors::{struct_span_err, Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported}; use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind}; use rustc_hir::def::Namespace::*; use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes}; @@ -713,7 +713,7 @@ struct PrivacyError<'a> { } struct UseError<'a> { - err: DiagnosticBuilder<'a>, + err: DiagnosticBuilder<'a, ErrorReported>, /// Candidates which user could `use` to access the missing type. candidates: Vec, /// The `DefId` of the module to place the use-statements in. diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 5c71bef31c2f2..e287764a52abc 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -7,7 +7,7 @@ use rustc_ast::node_id::NodeId; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler}; -use rustc_errors::{error_code, Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{error_code, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported}; use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; use rustc_span::edition::Edition; use rustc_span::hygiene::ExpnId; @@ -82,7 +82,7 @@ pub fn feature_err<'a>( feature: Symbol, span: impl Into, explain: &str, -) -> DiagnosticBuilder<'a> { +) -> DiagnosticBuilder<'a, ErrorReported> { feature_err_issue(sess, feature, span, GateIssue::Language, explain) } @@ -96,7 +96,7 @@ pub fn feature_err_issue<'a>( span: impl Into, issue: GateIssue, explain: &str, -) -> DiagnosticBuilder<'a> { +) -> DiagnosticBuilder<'a, ErrorReported> { let mut err = sess.span_diagnostic.struct_span_err_with_code(span, explain, error_code!(E0658)); if let Some(n) = find_feature_issue(feature, issue) { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 0515c440ab8fc..b72be735ce485 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -221,7 +221,7 @@ enum DiagnosticBuilderMethod { pub trait SessionDiagnostic<'a> { /// Write out as a diagnostic out of `sess`. #[must_use] - fn into_diagnostic(self, sess: &'a Session) -> DiagnosticBuilder<'a>; + fn into_diagnostic(self, sess: &'a Session) -> DiagnosticBuilder<'a, ErrorReported>; } /// Diagnostic message ID, used by `Session.one_time_diagnostics` to avoid @@ -303,7 +303,11 @@ impl Session { self.crate_types.set(crate_types).expect("`crate_types` was initialized twice") } - pub fn struct_span_warn>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_span_warn>( + &self, + sp: S, + msg: &str, + ) -> DiagnosticBuilder<'_, ()> { self.diagnostic().struct_span_warn(sp, msg) } pub fn struct_span_warn_with_code>( @@ -311,19 +315,27 @@ impl Session { sp: S, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'_, ()> { self.diagnostic().struct_span_warn_with_code(sp, msg, code) } - pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_, ()> { self.diagnostic().struct_warn(msg) } - pub fn struct_span_allow>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_span_allow>( + &self, + sp: S, + msg: &str, + ) -> DiagnosticBuilder<'_, ()> { self.diagnostic().struct_span_allow(sp, msg) } - pub fn struct_allow(&self, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_allow(&self, msg: &str) -> DiagnosticBuilder<'_, ()> { self.diagnostic().struct_allow(msg) } - pub fn struct_span_err>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_span_err>( + &self, + sp: S, + msg: &str, + ) -> DiagnosticBuilder<'_, ErrorReported> { self.diagnostic().struct_span_err(sp, msg) } pub fn struct_span_err_with_code>( @@ -331,17 +343,25 @@ impl Session { sp: S, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'_, ErrorReported> { self.diagnostic().struct_span_err_with_code(sp, msg, code) } // FIXME: This method should be removed (every error should have an associated error code). - pub fn struct_err(&self, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_err(&self, msg: &str) -> DiagnosticBuilder<'_, ErrorReported> { self.diagnostic().struct_err(msg) } - pub fn struct_err_with_code(&self, msg: &str, code: DiagnosticId) -> DiagnosticBuilder<'_> { + pub fn struct_err_with_code( + &self, + msg: &str, + code: DiagnosticId, + ) -> DiagnosticBuilder<'_, ErrorReported> { self.diagnostic().struct_err_with_code(msg, code) } - pub fn struct_span_fatal>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_span_fatal>( + &self, + sp: S, + msg: &str, + ) -> DiagnosticBuilder<'_, ErrorReported> { self.diagnostic().struct_span_fatal(sp, msg) } pub fn struct_span_fatal_with_code>( @@ -349,10 +369,10 @@ impl Session { sp: S, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'_, ErrorReported> { self.diagnostic().struct_span_fatal_with_code(sp, msg, code) } - pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_, ErrorReported> { self.diagnostic().struct_fatal(msg) } @@ -386,7 +406,7 @@ impl Session { pub fn err(&self, msg: &str) { self.diagnostic().err(msg) } - pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) { + pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorReported { err.into_diagnostic(self).emit() } #[inline] @@ -457,7 +477,7 @@ impl Session { pub fn span_note_without_error>(&self, sp: S, msg: &str) { self.diagnostic().span_note_without_error(sp, msg) } - pub fn struct_note_without_error(&self, msg: &str) -> DiagnosticBuilder<'_> { + pub fn struct_note_without_error(&self, msg: &str) -> DiagnosticBuilder<'_, ()> { self.diagnostic().struct_note_without_error(msg) } 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 c8d9ddb4a4d35..f26f32aabda1d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -102,7 +102,7 @@ pub trait InferCtxtExt<'tcx> { expected_args: Vec, found_args: Vec, is_closure: bool, - ) -> DiagnosticBuilder<'tcx>; + ) -> DiagnosticBuilder<'tcx, ErrorReported>; } impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { @@ -1019,7 +1019,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { expected_args: Vec, found_args: Vec, is_closure: bool, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let kind = if is_closure { "closure" } else { "function" }; let args_str = |arguments: &[ArgKind], other: &[ArgKind]| { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 293f388ff9cee..c4fbd25b8338b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -10,7 +10,8 @@ use crate::traits::normalize_projection_type; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{ - error_code, pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, Style, + error_code, pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, + ErrorReported, Style, }; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -122,7 +123,7 @@ pub trait InferCtxtExt<'tcx> { found_span: Option, expected_ref: ty::PolyTraitRef<'tcx>, found: ty::PolyTraitRef<'tcx>, - ) -> DiagnosticBuilder<'tcx>; + ) -> DiagnosticBuilder<'tcx, ErrorReported>; fn suggest_fully_qualified_path( &self, @@ -1271,7 +1272,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { found_span: Option, expected_ref: ty::PolyTraitRef<'tcx>, found: ty::PolyTraitRef<'tcx>, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { crate fn build_fn_sig_string<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 38a6220082ff6..acf1c976afcd9 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -450,7 +450,7 @@ fn report_conflicting_impls( sg.has_errored = true; 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)); + decorate(LintDiagnosticBuilder::new(err.forget_guarantee())); } else { tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"); } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index dbe7ddeb6a824..efa50375c95ea 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -15,7 +15,7 @@ use crate::middle::resolve_lifetime as rl; use crate::require_c_abi_if_c_variadic; use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{struct_span_err, Applicability, ErrorReported, FatalError}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported, FatalError}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -2618,7 +2618,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, constrained_regions: FxHashSet, referenced_regions: FxHashSet, - generate_err: impl Fn(&str) -> rustc_errors::DiagnosticBuilder<'tcx>, + generate_err: impl Fn(&str) -> DiagnosticBuilder<'tcx, ErrorReported>, ) { for br in referenced_regions.difference(&constrained_regions) { let br_name = match *br { diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs index 57076d9724678..cd24969bf283b 100644 --- a/compiler/rustc_typeck/src/check/cast.rs +++ b/compiler/rustc_typeck/src/check/cast.rs @@ -179,7 +179,7 @@ fn make_invalid_casting_error<'a, 'tcx>( expr_ty: Ty<'tcx>, cast_ty: Ty<'tcx>, fcx: &FnCtxt<'a, 'tcx>, -) -> DiagnosticBuilder<'a> { +) -> DiagnosticBuilder<'a, ErrorReported> { type_error_struct!( sess, span, diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 30ae382de4278..7dca95ebdd613 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -37,14 +37,16 @@ pub fn check_wf_new(tcx: TyCtxt<'_>) { pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) { match tcx.sess.target.is_abi_supported(abi) { Some(true) => (), - Some(false) => struct_span_err!( - tcx.sess, - span, - E0570, - "`{}` is not a supported ABI for the current target", - abi - ) - .emit(), + Some(false) => { + struct_span_err!( + tcx.sess, + span, + E0570, + "`{}` is not a supported ABI for the current target", + abi + ) + .emit(); + } 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() @@ -60,7 +62,7 @@ pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab E0781, "the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers" ) - .emit() + .emit(); } } diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index ed68bcfe433f8..8ca27b010b6af 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -37,7 +37,7 @@ use crate::astconv::AstConv; use crate::check::FnCtxt; -use rustc_errors::{struct_span_err, Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; @@ -1520,7 +1520,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fcx: &FnCtxt<'a, 'tcx>, id: hir::HirId, expression: Option<(&'tcx hir::Expr<'tcx>, hir::HirId)>, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'a, ErrorReported> { let mut err = fcx.report_mismatched_types(cause, expected, found, ty_err); let mut pointing_at_return_type = false; diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index 4e22e41588ad8..80096b90f9530 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -4,7 +4,7 @@ use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::ObligationCause; use rustc_ast::util::parser::PREC_POSTFIX; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported}; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_hir::{is_range_literal, Node}; @@ -57,7 +57,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Option> { + ) -> Option> { self.demand_suptype_with_origin(&self.misc(sp), expected, actual) } @@ -67,7 +67,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Option> { + ) -> Option> { match self.at(cause, self.param_env).sup(expected, actual) { Ok(InferOk { obligations, value: () }) => { self.register_predicates(obligations); @@ -88,7 +88,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Option> { + ) -> Option> { self.demand_eqtype_with_origin(&self.misc(sp), expected, actual) } @@ -97,7 +97,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Option> { + ) -> Option> { match self.at(cause, self.param_env).eq(expected, actual) { Ok(InferOk { obligations, value: () }) => { self.register_predicates(obligations); @@ -134,7 +134,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, allow_two_phase: AllowTwoPhase, - ) -> (Ty<'tcx>, Option>) { + ) -> (Ty<'tcx>, Option>) { let expected = self.resolve_vars_with_obligations(expected); let e = match self.try_coerce(expr, checked_ty, expected, allow_two_phase, None) { diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index a335295587e7c..f84036a7a3990 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -486,7 +486,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map_or(false, |x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_)))) }); if !is_named { - self.tcx.sess.emit_err(AddressOfTemporaryTaken { span: oprnd.span }) + self.tcx.sess.emit_err(AddressOfTemporaryTaken { span: oprnd.span }); } } @@ -1470,14 +1470,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.register_predicates(obligations) } // FIXME: Need better diagnostics for `FieldMisMatch` error - Err(_) => self - .report_mismatched_types( + Err(_) => { + self.report_mismatched_types( &cause, target_ty, fru_ty, FieldMisMatch(variant.name, ident.name), ) - .emit(), + .emit(); + } } } fru_ty @@ -1485,22 +1486,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .collect() } _ => { - return self - .report_mismatched_types( - &self.misc(base_expr.span), - adt_ty, - base_ty, - Sorts(ExpectedFound::new(true, adt_ty, base_ty)), - ) - .emit(); + self.report_mismatched_types( + &self.misc(base_expr.span), + adt_ty, + base_ty, + Sorts(ExpectedFound::new(true, adt_ty, base_ty)), + ) + .emit(); + return; } } } _ => { - return self - .tcx + self.tcx .sess .emit_err(FunctionalRecordUpdateOnNonStruct { span: base_expr.span }); + return; } } } else { @@ -1529,10 +1530,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) .collect(), _ => { - return self - .tcx + self.tcx .sess .emit_err(FunctionalRecordUpdateOnNonStruct { span: base_expr.span }); + return; } } }; @@ -2213,7 +2214,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field: Ident, expr_t: Ty<'tcx>, id: HirId, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'_, ErrorReported> { let span = field.span; debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 982fd49d0fac4..4b6460b62b77a 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -460,7 +460,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn variadic_error<'tcx>(sess: &Session, span: Span, ty: Ty<'tcx>, cast_ty: &str) { use crate::structured_errors::MissingCastForVariadicArg; - MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit() + MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit(); } for arg in provided_args.iter().skip(expected_arg_count) { diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 8ac7b5ca464df..ccaea10233dc1 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -3,7 +3,9 @@ use crate::check::FnCtxt; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{ + pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported, +}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; @@ -91,7 +93,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { source: SelfSource<'tcx>, error: MethodError<'tcx>, args: Option<&'tcx [hir::Expr<'tcx>]>, - ) -> Option> { + ) -> Option> { // Avoid suggestions when we don't know what's going on. if rcvr_ty.references_error() { return None; diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 3e01d73b0ba68..7c6917734b2ae 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -2,7 +2,9 @@ use crate::check::FnCtxt; use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{ + pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported, +}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; @@ -98,7 +100,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { expected: Ty<'tcx>, actual: Ty<'tcx>, ti: TopInfo<'tcx>, - ) -> Option> { + ) -> Option> { self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual) } @@ -817,7 +819,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn emit_bad_pat_path<'b>( &self, - mut e: DiagnosticBuilder<'_>, + mut e: DiagnosticBuilder<'_, ErrorReported>, pat_span: Span, res: Res, pat_res: Res, @@ -1368,7 +1370,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { variant: &VariantDef, pat: &'_ Pat<'_>, fields: &[hir::PatField<'_>], - ) -> Option> { + ) -> Option> { // if this is a tuple struct, then all field names will be numbers // so if any fields in a struct pattern use shorthand syntax, they will // be invalid identifiers (for example, Foo { 0, 1 }). @@ -1441,7 +1443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { inexistent_fields: &[Ident], unmentioned_fields: &mut Vec<(&ty::FieldDef, Ident)>, variant: &ty::VariantDef, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let tcx = self.tcx; let (field_names, t, plural) = if inexistent_fields.len() == 1 { (format!("a field named `{}`", inexistent_fields[0]), "this", "") @@ -1537,7 +1539,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat: &Pat<'_>, fields: &'tcx [hir::PatField<'tcx>], variant: &ty::VariantDef, - ) -> Option> { + ) -> Option> { if let (CtorKind::Fn, PatKind::Struct(qpath, ..)) = (variant.ctor_kind, &pat.kind) { let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| { s.print_qpath(qpath, false) @@ -1619,7 +1621,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, pat: &Pat<'_>, fields: &'tcx [hir::PatField<'tcx>], - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = self .tcx .sess @@ -1711,7 +1713,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { unmentioned_fields: &[(&ty::FieldDef, Ident)], have_inaccessible_fields: bool, fields: &'tcx [hir::PatField<'tcx>], - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let inaccessible = if have_inaccessible_fields { " and inaccessible fields" } else { "" }; let field_names = if unmentioned_fields.len() == 1 { format!("field `{}`{}", unmentioned_fields[0].1, inaccessible) diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 55757251e26fd..4ab654560ea0d 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -4,7 +4,7 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit as hir_visit; @@ -448,7 +448,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe for more information", ); - err.emit() + err.emit(); } } } @@ -843,7 +843,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { "using {} as const generic parameters is forbidden", unsupported_type ), - ) + ); } else { let mut err = tcx.sess.struct_span_err( hir_ty.span, @@ -858,7 +858,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { "more complex types are supported with `#![feature(adt_const_params)]`", ); } - err.emit() + err.emit(); } }; @@ -1729,12 +1729,14 @@ fn check_variances_for_type_defn<'tcx>( match param.name { hir::ParamName::Error => {} - _ => report_bivariance(tcx, param), + _ => { + report_bivariance(tcx, param); + } } } } -fn report_bivariance(tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>) { +fn report_bivariance(tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>) -> ErrorReported { let span = param.span; let param_name = param.name.ident().name; let mut err = error_392(tcx, span, param_name); @@ -1943,7 +1945,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -fn error_392(tcx: TyCtxt<'_>, span: Span, param_name: Symbol) -> DiagnosticBuilder<'_> { +fn error_392( + tcx: TyCtxt<'_>, + span: Span, + param_name: Symbol, +) -> DiagnosticBuilder<'_, ErrorReported> { let mut err = struct_span_err!(tcx.sess, span, E0392, "parameter `{}` is never used", param_name); err.span_label(span, "unused parameter"); diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs index 401ba188728c1..d058bca04a766 100644 --- a/compiler/rustc_typeck/src/coherence/builtin.rs +++ b/compiler/rustc_typeck/src/coherence/builtin.rs @@ -93,7 +93,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { for span in fields.iter().map(|f| tcx.def_span(f.did)) { err.span_label(span, "this field does not implement `Copy`"); } - err.emit() + err.emit(); } Err(CopyImplementationError::NotAnAdt) => { let item = tcx.hir().expect_item(impl_did); diff --git a/compiler/rustc_typeck/src/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs index 54fffeb3cdaa6..c72f3ecab9d13 100644 --- a/compiler/rustc_typeck/src/coherence/orphan.rs +++ b/compiler/rustc_typeck/src/coherence/orphan.rs @@ -159,7 +159,7 @@ fn emit_orphan_check_error<'tcx>( generics: &hir::Generics<'tcx>, err: traits::OrphanCheckErr<'tcx>, ) -> Result { - match err { + Err(match err { traits::OrphanCheckErr::NonLocalInputType(tys) => { let mut err = struct_span_err!( tcx.sess, @@ -269,9 +269,7 @@ fn emit_orphan_check_error<'tcx>( .emit(), } } - } - - Err(ErrorReported) + }) } #[derive(Default)] diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 392144ca7639c..139bac72ac23f 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -26,7 +26,7 @@ use rustc_ast::{MetaItemKind, NestedMetaItem}; use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; -use rustc_errors::{struct_span_err, Applicability}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; @@ -321,7 +321,7 @@ fn bad_placeholder<'tcx>( tcx: TyCtxt<'tcx>, mut spans: Vec, kind: &'static str, -) -> rustc_errors::DiagnosticBuilder<'tcx> { +) -> DiagnosticBuilder<'tcx, ErrorReported> { let kind = if kind.ends_with('s') { format!("{}es", kind) } else { format!("{}s", kind) }; spans.sort(); @@ -1277,19 +1277,21 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef { return None; } - Some(item) => tcx - .sess - .struct_span_err(item.span, "Not a function") - .span_note(attr_span, "required by this annotation") - .note( - "All `#[rustc_must_implement_one_of]` arguments \ + Some(item) => { + tcx.sess + .struct_span_err(item.span, "Not a function") + .span_note(attr_span, "required by this annotation") + .note( + "All `#[rustc_must_implement_one_of]` arguments \ must be associated function names", - ) - .emit(), - None => tcx - .sess - .struct_span_err(ident.span, "Function not found in this trait") - .emit(), + ) + .emit(); + } + None => { + tcx.sess + .struct_span_err(ident.span, "Function not found in this trait") + .emit(); + } } Some(()) diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs index 78097e3697fb9..6cef3e9d9409e 100644 --- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs @@ -393,13 +393,14 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc tcx.def_path_str(trait_ref.def_id), ), ) - .emit() + .emit(); } } - _ => tcx - .sess - .struct_span_err(span, &format!("cannot specialize on `{:?}`", predicate)) - .emit(), + _ => { + tcx.sess + .struct_span_err(span, &format!("cannot specialize on `{:?}`", predicate)) + .emit(); + } } } diff --git a/compiler/rustc_typeck/src/structured_errors.rs b/compiler/rustc_typeck/src/structured_errors.rs index 04d04304e70f9..8621375fc63e0 100644 --- a/compiler/rustc_typeck/src/structured_errors.rs +++ b/compiler/rustc_typeck/src/structured_errors.rs @@ -6,7 +6,7 @@ pub use self::{ missing_cast_for_variadic_arg::*, sized_unsized_cast::*, wrong_number_of_generic_args::*, }; -use rustc_errors::{DiagnosticBuilder, DiagnosticId}; +use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorReported}; use rustc_session::Session; pub trait StructuredDiagnostic<'tcx> { @@ -14,7 +14,7 @@ pub trait StructuredDiagnostic<'tcx> { fn code(&self) -> DiagnosticId; - fn diagnostic(&self) -> DiagnosticBuilder<'tcx> { + fn diagnostic(&self) -> DiagnosticBuilder<'tcx, ErrorReported> { let err = self.diagnostic_common(); if self.session().teach(&self.code()) { @@ -24,13 +24,19 @@ pub trait StructuredDiagnostic<'tcx> { } } - fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx>; + fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx, ErrorReported>; - fn diagnostic_regular(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> { + fn diagnostic_regular( + &self, + err: DiagnosticBuilder<'tcx, ErrorReported>, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { err } - fn diagnostic_extended(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> { + fn diagnostic_extended( + &self, + err: DiagnosticBuilder<'tcx, ErrorReported>, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { err } } diff --git a/compiler/rustc_typeck/src/structured_errors/missing_cast_for_variadic_arg.rs b/compiler/rustc_typeck/src/structured_errors/missing_cast_for_variadic_arg.rs index 4e29dda777646..2dc9f26004cf8 100644 --- a/compiler/rustc_typeck/src/structured_errors/missing_cast_for_variadic_arg.rs +++ b/compiler/rustc_typeck/src/structured_errors/missing_cast_for_variadic_arg.rs @@ -1,5 +1,5 @@ use crate::structured_errors::StructuredDiagnostic; -use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId}; +use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorReported}; use rustc_middle::ty::{Ty, TypeFoldable}; use rustc_session::Session; use rustc_span::Span; @@ -20,7 +20,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for MissingCastForVariadicArg<'tcx> { rustc_errors::error_code!(E0617) } - fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> { + fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = self.sess.struct_span_fatal_with_code( self.span, &format!("can't pass `{}` to variadic function", self.ty), @@ -45,7 +45,10 @@ impl<'tcx> StructuredDiagnostic<'tcx> for MissingCastForVariadicArg<'tcx> { err } - fn diagnostic_extended(&self, mut err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> { + fn diagnostic_extended( + &self, + mut err: DiagnosticBuilder<'tcx, ErrorReported>, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { err.note(&format!( "certain types, like `{}`, must be casted before passing them to a \ variadic function, because of arcane ABI rules dictated by the C \ diff --git a/compiler/rustc_typeck/src/structured_errors/sized_unsized_cast.rs b/compiler/rustc_typeck/src/structured_errors/sized_unsized_cast.rs index a622f0ca95a68..8d2cdbb170b98 100644 --- a/compiler/rustc_typeck/src/structured_errors/sized_unsized_cast.rs +++ b/compiler/rustc_typeck/src/structured_errors/sized_unsized_cast.rs @@ -1,5 +1,5 @@ use crate::structured_errors::StructuredDiagnostic; -use rustc_errors::{DiagnosticBuilder, DiagnosticId}; +use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorReported}; use rustc_middle::ty::{Ty, TypeFoldable}; use rustc_session::Session; use rustc_span::Span; @@ -20,7 +20,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for SizedUnsizedCast<'tcx> { rustc_errors::error_code!(E0607) } - fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> { + fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = self.sess.struct_span_fatal_with_code( self.span, &format!( @@ -37,7 +37,10 @@ impl<'tcx> StructuredDiagnostic<'tcx> for SizedUnsizedCast<'tcx> { err } - fn diagnostic_extended(&self, mut err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> { + fn diagnostic_extended( + &self, + mut err: DiagnosticBuilder<'tcx, ErrorReported>, + ) -> DiagnosticBuilder<'tcx, ErrorReported> { err.help( "Thin pointers are \"simple\" pointers: they are purely a reference to a memory address. diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs index 014d26280653b..b763b51dd0143 100644 --- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs @@ -1,5 +1,7 @@ use crate::structured_errors::StructuredDiagnostic; -use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId}; +use rustc_errors::{ + pluralize, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId, ErrorReported, +}; use rustc_hir as hir; use rustc_middle::hir::map::fn_sig; use rustc_middle::middle::resolve_lifetime::LifetimeScopeForPath; @@ -362,7 +364,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { } } - fn start_diagnostics(&self) -> DiagnosticBuilder<'tcx> { + fn start_diagnostics(&self) -> DiagnosticBuilder<'tcx, ErrorReported> { let span = self.path_segment.ident.span; let msg = self.create_error_message(); @@ -789,7 +791,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for WrongNumberOfGenericArgs<'_, 'tcx> { rustc_errors::error_code!(E0107) } - fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> { + fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx, ErrorReported> { let mut err = self.start_diagnostics(); self.notify(&mut err); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 7eff725989cc9..9d3e58a3a66fc 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -720,12 +720,10 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>( let mut msg = tcx.sess.struct_err(&format!("couldn't generate documentation: {}", e.error)); let file = e.file.display().to_string(); - if file.is_empty() { - msg.emit() - } else { - msg.note(&format!("failed to create or modify \"{}\"", file)).emit() + if !file.is_empty() { + msg.note(&format!("failed to create or modify \"{}\"", file)); } - Err(ErrorReported) + Err(msg.emit()) } } }