diff options
| author | bors <bors@rust-lang.org> | 2022-02-25 00:46:04 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-02-25 00:46:04 +0000 |
| commit | d4de1f230ca30b7ce08fbf453daebf8b2e7ffcc9 (patch) | |
| tree | 922a1d8bf2850b2f35dda5bc6cc14e9194c375c1 /compiler/rustc_trait_selection | |
| parent | 4e82f35492ea5c78e19609bf4468f0a686d9a756 (diff) | |
| parent | b7e95dee65c35db8f8e07046d445b12d92cbae12 (diff) | |
| download | rust-d4de1f230ca30b7ce08fbf453daebf8b2e7ffcc9.tar.gz rust-d4de1f230ca30b7ce08fbf453daebf8b2e7ffcc9.zip | |
Auto merge of #93368 - eddyb:diagbld-guarantee, r=estebank
rustc_errors: let `DiagnosticBuilder::emit` return a "guarantee of emission".
That is, `DiagnosticBuilder` is now generic over the return type of `.emit()`, so we'll now have:
* `DiagnosticBuilder<ErrorReported>` for error (incl. fatal/bug) diagnostics
* can only be created via a `const L: Level`-generic constructor, that limits allowed variants via a `where` clause, so not even `rustc_errors` can accidentally bypass this limitation
* asserts `diagnostic.is_error()` on emission, just in case the construction restriction was bypassed (e.g. by replacing the whole `Diagnostic` inside `DiagnosticBuilder`)
* `.emit()` returns `ErrorReported`, as a "proof" token that `.emit()` was called
(though note that this isn't a real guarantee until after completing the work on
#69426)
* `DiagnosticBuilder<()>` for everything else (warnings, notes, etc.)
* can also be obtained from other `DiagnosticBuilder`s by calling `.forget_guarantee()`
This PR is a companion to other ongoing work, namely:
* #69426
and it's ongoing implementation:
#93222
the API changes in this PR are needed to get statically-checked "only errors produce `ErrorReported` from `.emit()`", but doesn't itself provide any really strong guarantees without those other `ErrorReported` changes
* #93244
would make the choices of API changes (esp. naming) in this PR fit better overall
In order to be able to let `.emit()` return anything trustable, several changes had to be made:
* `Diagnostic`'s `level` field is now private to `rustc_errors`, to disallow arbitrary "downgrade"s from "some kind of error" to "warning" (or anything else that doesn't cause compilation to fail)
* it's still possible to replace the whole `Diagnostic` inside the `DiagnosticBuilder`, sadly, that's harder to fix, but it's unlikely enough that we can paper over it with asserts on `.emit()`
* `.cancel()` now consumes `DiagnosticBuilder`, preventing `.emit()` calls on a cancelled diagnostic
* it's also now done internally, through `DiagnosticBuilder`-private state, instead of having a `Level::Cancelled` variant that can be read (or worse, written) by the user
* this removes a hazard of calling `.cancel()` on an error then continuing to attach details to it, and even expect to be able to `.emit()` it
* warnings were switched to *only* `can_emit_warnings` on emission (instead of pre-cancelling early)
* `struct_dummy` was removed (as it relied on a pre-`Cancelled` `Diagnostic`)
* since `.emit()` doesn't consume the `DiagnosticBuilder` <sub>(I tried and gave up, it's much more work than this PR)</sub>,
we have to make `.emit()` idempotent wrt the guarantees it returns
* thankfully, `err.emit(); err.emit();` can return `ErrorReported` both times, as the second `.emit()` call has no side-effects *only* because the first one did do the appropriate emission
* `&mut Diagnostic` is now used in a lot of function signatures, which used to take `&mut DiagnosticBuilder` (in the interest of not having to make those functions generic)
* the APIs were already mostly identical, allowing for low-effort porting to this new setup
* only some of the suggestion methods needed some rework, to have the extra `DiagnosticBuilder` functionality on the `Diagnostic` methods themselves (that change is also present in #93259)
* `.emit()`/`.cancel()` aren't available, but IMO calling them from an "error decorator/annotator" function isn't a good practice, and can lead to strange behavior (from the caller's perspective)
* `.downgrade_to_delayed_bug()` was added, letting you convert any `.is_error()` diagnostic into a `delay_span_bug` one (which works because in both cases the guarantees available are the same)
This PR should ideally be reviewed commit-by-commit, since there is a lot of fallout in each.
r? `@estebank` cc `@Manishearth` `@nikomatsakis` `@mark-i-m`
Diffstat (limited to 'compiler/rustc_trait_selection')
6 files changed, 84 insertions, 121 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 8b76f3f7151..0f6997054b9 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -14,6 +14,7 @@ use crate::traits::{ PredicateObligations, SelectionContext, }; //use rustc_data_structures::fx::FxHashMap; +use rustc_errors::Diagnostic; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::CRATE_HIR_ID; use rustc_infer::infer::TyCtxtInferExt; @@ -50,7 +51,7 @@ pub struct OverlapResult<'tcx> { pub involves_placeholder: bool, } -pub fn add_placeholder_note(err: &mut rustc_errors::DiagnosticBuilder<'_>) { +pub fn add_placeholder_note(err: &mut Diagnostic) { err.note( "this behavior recently changed as a result of a bug fix; \ see rust-lang/rust#56105 for details", 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 8746d66ebb6..f26f32aabda 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -12,7 +12,9 @@ use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCod use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorReported}; +use rustc_errors::{ + pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported, +}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; @@ -100,7 +102,7 @@ pub trait InferCtxtExt<'tcx> { expected_args: Vec<ArgKind>, found_args: Vec<ArgKind>, is_closure: bool, - ) -> DiagnosticBuilder<'tcx>; + ) -> DiagnosticBuilder<'tcx, ErrorReported>; } impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { @@ -1017,7 +1019,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { expected_args: Vec<ArgKind>, found_args: Vec<ArgKind>, is_closure: bool, - ) -> DiagnosticBuilder<'tcx> { + ) -> DiagnosticBuilder<'tcx, ErrorReported> { let kind = if is_closure { "closure" } else { "function" }; let args_str = |arguments: &[ArgKind], other: &[ArgKind]| { @@ -1174,7 +1176,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> { fn report_similar_impl_candidates( &self, impl_candidates: Vec<ImplCandidate<'tcx>>, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, ); /// Gets the parent trait chain start @@ -1186,11 +1188,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> { /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait /// with the same path as `trait_ref`, a help message about /// a probable version mismatch is added to `err` - fn note_version_mismatch( - &self, - err: &mut DiagnosticBuilder<'_>, - trait_ref: &ty::PolyTraitRef<'tcx>, - ); + fn note_version_mismatch(&self, err: &mut Diagnostic, trait_ref: &ty::PolyTraitRef<'tcx>); /// Creates a `PredicateObligation` with `new_self_ty` replacing the existing type in the /// `trait_ref`. @@ -1215,35 +1213,26 @@ trait InferCtxtPrivExt<'hir, 'tcx> { pred: ty::PolyTraitRef<'tcx>, ) -> bool; - fn note_obligation_cause( - &self, - err: &mut DiagnosticBuilder<'tcx>, - obligation: &PredicateObligation<'tcx>, - ); + fn note_obligation_cause(&self, err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>); fn suggest_unsized_bound_if_applicable( &self, - err: &mut DiagnosticBuilder<'tcx>, + err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>, ); fn annotate_source_of_ambiguity( &self, - err: &mut DiagnosticBuilder<'tcx>, + err: &mut Diagnostic, impls: &[DefId], predicate: ty::Predicate<'tcx>, ); - fn maybe_suggest_unsized_generics( - &self, - err: &mut DiagnosticBuilder<'tcx>, - span: Span, - node: Node<'hir>, - ); + fn maybe_suggest_unsized_generics(&self, err: &mut Diagnostic, span: Span, node: Node<'hir>); fn maybe_indirection_for_unsized( &self, - err: &mut DiagnosticBuilder<'tcx>, + err: &mut Diagnostic, item: &'hir Item<'hir>, param: &'hir GenericParam<'hir>, ) -> bool; @@ -1572,7 +1561,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { fn report_similar_impl_candidates( &self, impl_candidates: Vec<ImplCandidate<'tcx>>, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, ) { if impl_candidates.is_empty() { return; @@ -1649,11 +1638,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait /// with the same path as `trait_ref`, a help message about /// a probable version mismatch is added to `err` - fn note_version_mismatch( - &self, - err: &mut DiagnosticBuilder<'_>, - trait_ref: &ty::PolyTraitRef<'tcx>, - ) { + fn note_version_mismatch(&self, err: &mut Diagnostic, trait_ref: &ty::PolyTraitRef<'tcx>) { let get_trait_impl = |trait_def_id| { self.tcx.find_map_relevant_impl(trait_def_id, trait_ref.skip_binder().self_ty(), Some) }; @@ -1944,7 +1929,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { fn annotate_source_of_ambiguity( &self, - err: &mut DiagnosticBuilder<'tcx>, + err: &mut Diagnostic, impls: &[DefId], predicate: ty::Predicate<'tcx>, ) { @@ -1977,7 +1962,9 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { // Avoid complaining about other inference issues for expressions like // `42 >> 1`, where the types are still `{integer}`, but we want to // Do we need `trait_ref.skip_binder().self_ty().is_numeric() &&` too? - err.cancel(); + // NOTE(eddyb) this was `.cancel()`, but `err` + // is borrowed, so we can't fully defuse it. + err.downgrade_to_delayed_bug(); return; } let post = if post.len() > 4 { @@ -2088,11 +2075,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { }) } - fn note_obligation_cause( - &self, - err: &mut DiagnosticBuilder<'tcx>, - obligation: &PredicateObligation<'tcx>, - ) { + fn note_obligation_cause(&self, err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>) { // First, attempt to add note to this error with an async-await-specific // message, and fall back to regular note otherwise. if !self.maybe_note_obligation_cause_for_async_await(err, obligation) { @@ -2110,7 +2093,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { fn suggest_unsized_bound_if_applicable( &self, - err: &mut DiagnosticBuilder<'tcx>, + err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>, ) { let (pred, item_def_id, span) = match ( @@ -2139,7 +2122,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { fn maybe_suggest_unsized_generics<'hir>( &self, - err: &mut DiagnosticBuilder<'tcx>, + err: &mut Diagnostic, span: Span, node: Node<'hir>, ) { @@ -2206,7 +2189,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { fn maybe_indirection_for_unsized<'hir>( &self, - err: &mut DiagnosticBuilder<'tcx>, + err: &mut Diagnostic, item: &'hir Item<'hir>, param: &'hir GenericParam<'hir>, ) -> bool { 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 e162e943e36..c4fbd25b833 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, DiagnosticBuilder, Style, + error_code, pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, + ErrorReported, Style, }; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -47,7 +48,7 @@ pub enum GeneratorInteriorOrUpvar { pub trait InferCtxtExt<'tcx> { fn suggest_restricting_param_bound( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, body_id: hir::HirId, ); @@ -55,28 +56,23 @@ pub trait InferCtxtExt<'tcx> { fn suggest_dereferences( &self, obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'tcx>, + err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ); - fn get_closure_name( - &self, - def_id: DefId, - err: &mut DiagnosticBuilder<'_>, - msg: &str, - ) -> Option<String>; + fn get_closure_name(&self, def_id: DefId, err: &mut Diagnostic, msg: &str) -> Option<String>; fn suggest_fn_call( &self, obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ); fn suggest_add_reference_to_arg( &self, obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, has_custom_message: bool, ) -> bool; @@ -84,27 +80,23 @@ pub trait InferCtxtExt<'tcx> { fn suggest_remove_reference( &self, obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ); - fn suggest_remove_await( - &self, - obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'_>, - ); + fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic); fn suggest_change_mut( &self, obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ); fn suggest_semicolon_removal( &self, obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, span: Span, trait_pred: ty::PolyTraitPredicate<'tcx>, ); @@ -113,7 +105,7 @@ pub trait InferCtxtExt<'tcx> { fn suggest_impl_trait( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, span: Span, obligation: &PredicateObligation<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>, @@ -121,7 +113,7 @@ pub trait InferCtxtExt<'tcx> { fn point_at_returns_when_relevant( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>, ); @@ -131,11 +123,11 @@ pub trait InferCtxtExt<'tcx> { found_span: Option<Span>, expected_ref: ty::PolyTraitRef<'tcx>, found: ty::PolyTraitRef<'tcx>, - ) -> DiagnosticBuilder<'tcx>; + ) -> DiagnosticBuilder<'tcx, ErrorReported>; fn suggest_fully_qualified_path( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, def_id: DefId, span: Span, trait_ref: DefId, @@ -143,13 +135,13 @@ pub trait InferCtxtExt<'tcx> { fn maybe_note_obligation_cause_for_async_await( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>, ) -> bool; fn note_obligation_cause_for_async_await( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, interior_or_upvar_span: GeneratorInteriorOrUpvar, interior_extra_info: Option<(Option<Span>, Span, Option<hir::HirId>, Option<Span>)>, inner_generator_body: Option<&hir::Body<'tcx>>, @@ -163,7 +155,7 @@ pub trait InferCtxtExt<'tcx> { fn note_obligation_cause_code<T>( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, predicate: &T, param_env: ty::ParamEnv<'tcx>, cause_code: &ObligationCauseCode<'tcx>, @@ -172,12 +164,12 @@ pub trait InferCtxtExt<'tcx> { ) where T: fmt::Display; - fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>); + fn suggest_new_overflow_limit(&self, err: &mut Diagnostic); /// Suggest to await before try: future? => future.await? fn suggest_await_before_try( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>, span: Span, @@ -202,7 +194,7 @@ fn suggest_restriction<'tcx>( tcx: TyCtxt<'tcx>, generics: &hir::Generics<'tcx>, msg: &str, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, fn_sig: Option<&hir::FnSig<'_>>, projection: Option<&ty::ProjectionTy<'_>>, trait_pred: ty::PolyTraitPredicate<'tcx>, @@ -329,7 +321,7 @@ fn suggest_restriction<'tcx>( impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn suggest_restricting_param_bound( &self, - mut err: &mut DiagnosticBuilder<'_>, + mut err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, body_id: hir::HirId, ) { @@ -493,7 +485,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn suggest_dereferences( &self, obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'tcx>, + err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ) { // It only make sense when suggesting dereferences for arguments @@ -549,26 +541,20 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { /// Given a closure's `DefId`, return the given name of the closure. /// /// This doesn't account for reassignments, but it's only used for suggestions. - fn get_closure_name( - &self, - def_id: DefId, - err: &mut DiagnosticBuilder<'_>, - msg: &str, - ) -> Option<String> { - let get_name = - |err: &mut DiagnosticBuilder<'_>, kind: &hir::PatKind<'_>| -> Option<String> { - // Get the local name of this closure. This can be inaccurate because - // of the possibility of reassignment, but this should be good enough. - match &kind { - hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, name, None) => { - Some(format!("{}", name)) - } - _ => { - err.note(&msg); - None - } + fn get_closure_name(&self, def_id: DefId, err: &mut Diagnostic, msg: &str) -> Option<String> { + let get_name = |err: &mut Diagnostic, kind: &hir::PatKind<'_>| -> Option<String> { + // Get the local name of this closure. This can be inaccurate because + // of the possibility of reassignment, but this should be good enough. + match &kind { + hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, name, None) => { + Some(format!("{}", name)) } - }; + _ => { + err.note(&msg); + None + } + } + }; let hir = self.tcx.hir(); let hir_id = hir.local_def_id_to_hir_id(def_id.as_local()?); @@ -590,7 +576,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn suggest_fn_call( &self, obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ) { let self_ty = match trait_pred.self_ty().no_bound_vars() { @@ -683,7 +669,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn suggest_add_reference_to_arg( &self, obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, poly_trait_pred: ty::PolyTraitPredicate<'tcx>, has_custom_message: bool, ) -> bool { @@ -817,7 +803,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn suggest_remove_reference( &self, obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ) { let span = obligation.cause.span; @@ -874,11 +860,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } } - fn suggest_remove_await( - &self, - obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'_>, - ) { + fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic) { let span = obligation.cause.span; if let ObligationCauseCode::AwaitableExpr(hir_id) = obligation.cause.code().peel_derives() { @@ -936,7 +918,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn suggest_change_mut( &self, obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ) { let points_at_arg = matches!( @@ -1012,7 +994,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn suggest_semicolon_removal( &self, obligation: &PredicateObligation<'tcx>, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, span: Span, trait_pred: ty::PolyTraitPredicate<'tcx>, ) { @@ -1063,7 +1045,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { /// emitted. fn suggest_impl_trait( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, span: Span, obligation: &PredicateObligation<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>, @@ -1256,7 +1238,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn point_at_returns_when_relevant( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>, ) { match obligation.cause.code().peel_derives() { @@ -1290,7 +1272,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { found_span: Option<Span>, 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>, @@ -1345,7 +1327,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn suggest_fully_qualified_path( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, def_id: DefId, span: Span, trait_ref: DefId, @@ -1411,7 +1393,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { /// Returns `true` if an async-await specific note was added to the diagnostic. fn maybe_note_obligation_cause_for_async_await( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>, ) -> bool { debug!( @@ -1639,7 +1621,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { /// `maybe_note_obligation_cause_for_async_await`'s documentation comment. fn note_obligation_cause_for_async_await( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, interior_or_upvar_span: GeneratorInteriorOrUpvar, interior_extra_info: Option<(Option<Span>, Span, Option<hir::HirId>, Option<Span>)>, inner_generator_body: Option<&hir::Body<'tcx>>, @@ -1896,7 +1878,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn note_obligation_cause_code<T>( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, predicate: &T, param_env: ty::ParamEnv<'tcx>, cause_code: &ObligationCauseCode<'tcx>, @@ -2133,7 +2115,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred); let ty = parent_trait_ref.skip_binder().self_ty(); if parent_trait_ref.references_error() { - err.cancel(); + // NOTE(eddyb) this was `.cancel()`, but `err` + // is borrowed, so we can't fully defuse it. + err.downgrade_to_delayed_bug(); return; } @@ -2412,7 +2396,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } } - fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>) { + fn suggest_new_overflow_limit(&self, err: &mut Diagnostic) { let suggested_limit = match self.tcx.recursion_limit() { Limit(0) => Limit(2), limit => limit * 2, @@ -2427,7 +2411,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn suggest_await_before_try( &self, - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>, span: Span, @@ -2615,7 +2599,7 @@ impl NextTypeParamName for &[hir::GenericParam<'_>] { } fn suggest_trait_object_return_type_alternatives( - err: &mut DiagnosticBuilder<'_>, + err: &mut Diagnostic, ret_ty: Span, trait_obj: &str, is_object_safe: bool, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 5b646c6d447..8bcb1ccb584 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -29,7 +29,7 @@ use crate::traits::project::ProjectionCacheKeyExt; use crate::traits::ProjectionCacheKey; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::ErrorReported; +use rustc_errors::{Diagnostic, ErrorReported}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::LateBoundRegionConversionTime; @@ -64,7 +64,7 @@ pub enum IntercrateAmbiguityCause { impl IntercrateAmbiguityCause { /// Emits notes when the overlap is caused by complex intercrate ambiguities. /// See #23980 for details. - pub fn add_intercrate_ambiguity_hint(&self, err: &mut rustc_errors::DiagnosticBuilder<'_>) { + pub fn add_intercrate_ambiguity_hint(&self, err: &mut Diagnostic) { err.note(&self.intercrate_ambiguity_hint()); } diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 38a6220082f..acf1c976afc 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_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index b6e653c0eea..f800e7a1402 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -1,4 +1,4 @@ -use rustc_errors::DiagnosticBuilder; +use rustc_errors::Diagnostic; use rustc_span::Span; use smallvec::smallvec; use smallvec::SmallVec; @@ -43,12 +43,7 @@ impl<'tcx> TraitAliasExpansionInfo<'tcx> { /// Adds diagnostic labels to `diag` for the expansion path of a trait through all intermediate /// trait aliases. - pub fn label_with_exp_info( - &self, - diag: &mut DiagnosticBuilder<'_>, - top_label: &str, - use_desc: &str, - ) { + pub fn label_with_exp_info(&self, diag: &mut Diagnostic, top_label: &str, use_desc: &str) { diag.span_label(self.top().1, top_label); if self.path.len() > 1 { for (_, sp) in self.path.iter().rev().skip(1).take(self.path.len() - 2) { |
