From b3b092de4de860dce7ca77ccee356698986fe69e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 13 Feb 2024 12:19:24 +1100 Subject: [PATCH 1/2] Optimize `delayed_bug` handling. Once we have emitted at least one error, delayed bugs won't be used. So we can (a) we can (a) discard any existing delayed bugs, and (b) stop recording any new delayed bugs. This eliminates a longstanding `FIXME` comment. There should be no soundness issues because it's not possible to un-emit an error. --- compiler/rustc_errors/src/lib.rs | 39 ++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index e033d66fccf41..18cf64d937e3b 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1275,6 +1275,9 @@ impl DiagCtxtInner { self.future_breakage_diagnostics.push(diagnostic.clone()); } + // Note that because this comes before the `match` below, + // `-Zeagerly-emit-delayed-bugs` continues to work even after we've + // issued an error and stopped recording new delayed bugs. if diagnostic.level == DelayedBug && self.flags.eagerly_emit_delayed_bugs { diagnostic.level = Error; } @@ -1286,18 +1289,20 @@ impl DiagCtxtInner { diagnostic.level = Bug; } DelayedBug => { - // FIXME(eddyb) this should check for `has_errors` and stop pushing - // once *any* errors were emitted (and truncate `delayed_bugs` - // when an error is first emitted, also), but maybe there's a case - // in which that's not sound? otherwise this is really inefficient. - let backtrace = std::backtrace::Backtrace::capture(); - // This `unchecked_error_guaranteed` is valid. It is where the - // `ErrorGuaranteed` for delayed bugs originates. - #[allow(deprecated)] - let guar = ErrorGuaranteed::unchecked_error_guaranteed(); - self.delayed_bugs - .push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar)); - return Some(guar); + // If we have already emitted at least one error, we don't need + // to record the delayed bug, because it'll never be used. + return if let Some(guar) = self.has_errors_or_lint_errors() { + Some(guar) + } else { + let backtrace = std::backtrace::Backtrace::capture(); + // This `unchecked_error_guaranteed` is valid. It is where the + // `ErrorGuaranteed` for delayed bugs originates. + #[allow(deprecated)] + let guar = ErrorGuaranteed::unchecked_error_guaranteed(); + self.delayed_bugs + .push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar)); + Some(guar) + }; } Warning if !self.flags.can_emit_warnings => { if diagnostic.has_future_breakage() { @@ -1363,6 +1368,16 @@ impl DiagCtxtInner { } if is_error { + // If we have any delayed bugs recorded, we can discard them + // because they won't be used. (This should only occur if there + // have been no errors previously emitted, because we don't add + // new delayed bugs once the first error is emitted.) + if !self.delayed_bugs.is_empty() { + assert_eq!(self.lint_err_guars.len() + self.err_guars.len(), 0); + self.delayed_bugs.clear(); + self.delayed_bugs.shrink_to_fit(); + } + // This `unchecked_error_guaranteed` is valid. It is where the // `ErrorGuaranteed` for errors and lint errors originates. #[allow(deprecated)] From 33a683375326d5ef62f5f9887e60169a931d7399 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 13 Feb 2024 12:28:29 +1100 Subject: [PATCH 2/2] Split delayed bugs into has-errored and will-error halves. This commit adds new `{span_,}assert_has_errors` methods implementing the simpler has-errored cases, and leaves the existing `{span_,}delayed_bug` methods for the will-error cases. It also converts as many cases as possible to has-errored. I did this by converting every case to has-errored, then running tests and converting back to will-error every case that caused an assertion in the test suite. The test suite doesn't have perfect coverage so it's possible that there are a few more has-errored cases that will need conversion back to will-error. Also, some of the will-error cases might actually be a mixture of has-errored and will-error. But it's hard to do this perfectly without carefully going through every individual case, which would be painful, and an imperfect split still gets most of the benefits. --- compiler/rustc_abi/src/layout.rs | 6 +-- compiler/rustc_ast_lowering/src/delegation.rs | 2 +- compiler/rustc_ast_lowering/src/expr.rs | 6 +-- compiler/rustc_ast_lowering/src/format.rs | 6 ++- compiler/rustc_ast_lowering/src/index.rs | 2 +- compiler/rustc_ast_lowering/src/item.rs | 10 +++-- compiler/rustc_ast_lowering/src/lib.rs | 14 ++++--- .../src/diagnostics/region_name.rs | 4 +- .../src/type_check/free_region_relations.rs | 2 +- .../src/type_check/input_output.rs | 7 ++-- compiler/rustc_borrowck/src/type_check/mod.rs | 4 +- .../rustc_codegen_ssa/src/codegen_attrs.rs | 6 ++- .../src/const_eval/machine.rs | 7 ++-- .../src/transform/check_consts/check.rs | 4 +- .../src/transform/check_consts/mod.rs | 2 +- .../src/transform/validate.rs | 6 +-- compiler/rustc_errors/src/lib.rs | 31 ++++++++++++++-- compiler/rustc_expand/src/mbe/diagnostics.rs | 4 +- .../rustc_hir_analysis/src/astconv/mod.rs | 4 +- .../src/astconv/object_safety.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 20 ++++++---- .../src/check/compare_impl_item.rs | 6 +-- .../src/check/compare_impl_item/refine.rs | 8 ++-- .../rustc_hir_analysis/src/check/dropck.rs | 2 +- .../src/check/intrinsicck.rs | 2 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 8 ++-- .../src/coherence/orphan.rs | 2 +- .../src/coherence/unsafety.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 2 +- .../src/collect/generics_of.rs | 2 +- .../src/collect/resolve_bound_vars.rs | 4 +- .../src/collect/type_of/opaque.rs | 2 +- .../rustc_hir_analysis/src/impl_wf_check.rs | 2 +- compiler/rustc_hir_typeck/src/cast.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 13 ++++--- .../rustc_hir_typeck/src/expr_use_visitor.rs | 4 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- compiler/rustc_hir_typeck/src/intrinsicck.rs | 2 +- .../src/mem_categorization.rs | 18 +++++---- compiler/rustc_hir_typeck/src/method/probe.rs | 2 +- .../rustc_hir_typeck/src/method/suggest.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 7 +++- compiler/rustc_hir_typeck/src/upvar.rs | 2 +- compiler/rustc_hir_typeck/src/writeback.rs | 4 +- .../src/infer/canonical/canonicalizer.rs | 4 +- .../src/infer/error_reporting/mod.rs | 7 ++-- .../src/infer/lexical_region_resolve/mod.rs | 2 +- .../src/infer/outlives/obligations.rs | 2 +- .../rustc_infer/src/infer/outlives/verify.rs | 2 +- compiler/rustc_infer/src/infer/relate/nll.rs | 2 +- compiler/rustc_lint/src/early.rs | 2 +- compiler/rustc_middle/src/middle/stability.rs | 3 +- .../rustc_middle/src/mir/interpret/mod.rs | 2 +- compiler/rustc_middle/src/query/plumbing.rs | 2 +- compiler/rustc_middle/src/ty/adt.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/layout.rs | 4 +- .../rustc_middle/src/ty/typeck_results.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 6 ++- .../src/build/expr/as_constant.rs | 28 +++++++------- compiler/rustc_mir_build/src/build/scope.rs | 2 +- .../rustc_mir_build/src/check_unsafety.rs | 2 +- compiler/rustc_mir_build/src/thir/constant.rs | 37 +++++++++---------- .../rustc_mir_build/src/thir/pattern/mod.rs | 4 +- .../rustc_mir_transform/src/check_unsafety.rs | 2 +- compiler/rustc_mir_transform/src/coroutine.rs | 2 +- .../src/elaborate_drops.rs | 4 +- compiler/rustc_mir_transform/src/lib.rs | 2 +- .../rustc_parse/src/parser/attr_wrapper.rs | 3 +- compiler/rustc_passes/src/hir_id_validator.rs | 2 +- compiler/rustc_passes/src/liveness.rs | 7 +++- .../rustc_query_system/src/query/plumbing.rs | 2 +- compiler/rustc_resolve/src/ident.rs | 2 +- compiler/rustc_resolve/src/late.rs | 2 +- .../src/solve/assembly/mod.rs | 10 ++--- .../src/solve/normalizes_to/mod.rs | 2 +- .../src/traits/const_evaluatable.rs | 4 +- .../error_reporting/on_unimplemented.rs | 3 +- .../error_reporting/type_err_ctxt_ext.rs | 6 +-- .../rustc_trait_selection/src/traits/mod.rs | 2 +- .../src/traits/object_safety.rs | 7 ++-- .../src/traits/outlives_bounds.rs | 2 +- .../src/traits/project.rs | 4 +- .../src/traits/query/type_op/custom.rs | 2 +- .../src/traits/query/type_op/mod.rs | 2 +- .../src/traits/specialize/mod.rs | 3 +- .../src/traits/structural_match.rs | 4 +- compiler/rustc_ty_utils/src/instance.rs | 4 +- compiler/rustc_ty_utils/src/layout.rs | 9 +++-- compiler/rustc_ty_utils/src/opaque_types.rs | 4 +- .../rust-analyzer/crates/hir-ty/src/layout.rs | 2 +- 92 files changed, 266 insertions(+), 200 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index ec3ab828b7194..7f153e9382685 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -32,7 +32,7 @@ where pub trait LayoutCalculator { type TargetDataLayoutRef: Borrow; - fn delayed_bug(&self, txt: String); + fn assert_has_errors(&self, txt: String); fn current_data_layout(&self) -> Self::TargetDataLayoutRef; fn scalar_pair( @@ -259,7 +259,7 @@ pub trait LayoutCalculator { let only_variant = &variants[VariantIdx::new(0)]; for field in only_variant { if field.is_unsized() { - self.delayed_bug("unsized field in union".to_string()); + self.assert_has_errors("unsized field in union".to_string()); } align = align.max(field.align); @@ -1092,7 +1092,7 @@ fn univariant< for &i in &inverse_memory_index { let field = &fields[i]; if !sized { - this.delayed_bug(format!( + this.assert_has_errors(format!( "univariant: field #{} comes after unsized field", offsets.len(), )); diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index d1ba93f067553..98a9c24157356 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -112,7 +112,7 @@ impl<'hir> LoweringContext<'_, 'hir> { sig_id.ok_or_else(|| { self.tcx .dcx() - .span_delayed_bug(span, "LoweringContext: couldn't resolve delegation item") + .span_assert_has_errors(span, "LoweringContext: couldn't resolve delegation item") }) } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 942aae3d53600..dc77a3375377b 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -323,9 +323,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ) } ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()), - ExprKind::Err => { - hir::ExprKind::Err(self.dcx().span_delayed_bug(e.span, "lowered ExprKind::Err")) - } + ExprKind::Err => hir::ExprKind::Err( + self.dcx().span_assert_has_errors(e.span, "lowered ExprKind::Err"), + ), ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr), ExprKind::Paren(_) | ExprKind::ForLoop { .. } => { diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 00cb09d7a541a..d5881e9f7c401 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -267,7 +267,7 @@ fn make_count<'hir>( ctx.expr( sp, hir::ExprKind::Err( - ctx.dcx().span_delayed_bug(sp, "lowered bad format_args count"), + ctx.dcx().span_assert_has_errors(sp, "lowered bad format_args count"), ), ) } @@ -306,7 +306,9 @@ fn make_format_spec<'hir>( } Err(_) => ctx.expr( sp, - hir::ExprKind::Err(ctx.dcx().span_delayed_bug(sp, "lowered bad format_args count")), + hir::ExprKind::Err( + ctx.dcx().span_assert_has_errors(sp, "lowered bad format_args count"), + ), ), }; let &FormatOptions { diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index 11aa6b250b129..673640c8cee0a 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -61,7 +61,7 @@ pub(super) fn index_hir<'hir>( if let Node::Err(span) = node.node { let hir_id = HirId { owner: item.def_id(), local_id }; let msg = format!("ID {hir_id} not encountered when visiting item HIR"); - tcx.dcx().span_delayed_bug(*span, msg); + tcx.dcx().span_assert_has_errors(*span, msg); } } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 933372fae4eb4..84c49c99836c4 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -266,7 +266,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| match ty { None => { - let guar = this.dcx().span_delayed_bug( + let guar = this.dcx().span_assert_has_errors( span, "expected to lower type alias type, but it was missing", ); @@ -925,7 +925,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| match ty { None => { - let guar = this.dcx().span_delayed_bug( + let guar = this.dcx().span_assert_has_errors( i.span, "expected to lower associated type, but it was missing", ); @@ -1068,7 +1068,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> { match block { Some(block) => self.lower_block_expr(block), - None => self.expr_err(span, self.dcx().span_delayed_bug(span, "no block")), + None => self.expr_err(span, self.dcx().span_assert_has_errors(span, "no block")), } } @@ -1078,7 +1078,9 @@ impl<'hir> LoweringContext<'_, 'hir> { &[], match expr { Some(expr) => this.lower_expr_mut(expr), - None => this.expr_err(span, this.dcx().span_delayed_bug(span, "no block")), + None => { + this.expr_err(span, this.dcx().span_assert_has_errors(span, "no block")) + } }, ) }) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 480072ce705aa..2a6af2cd62de4 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -747,7 +747,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let res = self.resolver.get_import_res(id).present_items(); let res: SmallVec<_> = res.map(|res| self.lower_res(res)).collect(); if res.is_empty() { - self.dcx().span_delayed_bug(span, "no resolution for an import"); + self.dcx().span_assert_has_errors(span, "no resolution for an import"); return smallvec![Res::Err]; } res @@ -1286,7 +1286,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let kind = match &t.kind { TyKind::Infer => hir::TyKind::Infer, TyKind::Err => { - hir::TyKind::Err(self.dcx().span_delayed_bug(t.span, "TyKind::Err lowered")) + hir::TyKind::Err(self.dcx().span_assert_has_errors(t.span, "TyKind::Err lowered")) } // Lower the anonymous structs or unions in a nested lowering context. // @@ -1499,7 +1499,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"), TyKind::CVarArgs => { - let guar = self.dcx().span_delayed_bug( + let guar = self.dcx().span_assert_has_errors( t.span, "`TyKind::CVarArgs` should have been handled elsewhere", ); @@ -1643,8 +1643,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { if let Some(old_def_id) = self.orig_opt_local_def_id(param) { old_def_id } else { - self.dcx() - .span_delayed_bug(lifetime.ident.span, "no def-id for fresh lifetime"); + self.dcx().span_assert_has_errors( + lifetime.ident.span, + "no def-id for fresh lifetime", + ); continue; } } @@ -2576,7 +2578,7 @@ impl<'hir> GenericArgsCtor<'hir> { let span = lcx.lower_span(span); let Some(host_param_id) = lcx.host_param_id else { - lcx.dcx().span_delayed_bug( + lcx.dcx().span_assert_has_errors( span, "no host param id for call in const yet no errors reported", ); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index e008d230656f9..0c0523f37d24f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -627,8 +627,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { _, ) => { // HIR lowering sometimes doesn't catch this in erroneous - // programs, so we need to use span_delayed_bug here. See #82126. - self.dcx().span_delayed_bug( + // programs, so we need to use span_assert_has_errors here. See #82126. + self.dcx().span_assert_has_errors( hir_arg.span(), format!("unmatched arg and hir arg: found {kind:?} vs {hir_arg:?}"), ); diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 2e0caf4481902..a2d93d0bf0af8 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -316,7 +316,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { .and(type_op::normalize::Normalize::new(ty)) .fully_perform(self.infcx, span) else { - tcx.dcx().span_delayed_bug(span, format!("failed to normalize {ty:?}")); + tcx.dcx().span_assert_has_errors(span, format!("failed to normalize {ty:?}")); continue; }; constraints.extend(c); diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index af5b635ae6688..74e414c9f98bd 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -152,9 +152,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // Equate expected input tys with those in the MIR. for (argument_index, &normalized_input_ty) in normalized_input_tys.iter().enumerate() { if argument_index + 1 >= body.local_decls.len() { - self.tcx() - .dcx() - .span_delayed_bug(body.span, "found more normalized_input_ty than local_decls"); + self.tcx().dcx().span_assert_has_errors( + body.span, + "found more normalized_input_ty than local_decls", + ); break; } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index cfb46f3ac8a96..20047b8bfeb6b 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -223,7 +223,7 @@ pub(crate) fn type_check<'mir, 'tcx>( let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind()); if hidden_type.has_non_region_infer() { - let reported = infcx.dcx().span_delayed_bug( + let reported = infcx.dcx().span_assert_has_errors( decl.hidden_type.span, format!("could not resolve {:#?}", hidden_type.ty.kind()), ); @@ -1089,7 +1089,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); if result.is_err() { - self.infcx.dcx().span_delayed_bug( + self.infcx.dcx().span_assert_has_errors( self.body.span, "failed re-defining predefined opaques in mir typeck", ); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 9e23757fceef0..7b2eb0e49cc39 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -90,8 +90,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { if let Fn | AssocFn | Variant | Ctor(..) = def_kind { Some(tcx.fn_sig(did)) } else { - tcx.dcx() - .span_delayed_bug(attr.span, "this attribute can only be applied to functions"); + tcx.dcx().span_assert_has_errors( + attr.span, + "this attribute can only be applied to functions", + ); None } }; diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index d08985edb76b0..fbd485704fe33 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -388,10 +388,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, if ecx.tcx.is_ctfe_mir_available(def) { Ok(ecx.tcx.mir_for_ctfe(def)) } else if ecx.tcx.def_kind(def) == DefKind::AssocConst { - let guar = ecx - .tcx - .dcx() - .delayed_bug("This is likely a const item that is missing from its impl"); + let guar = ecx.tcx.dcx().assert_has_errors( + "This is likely a const item that is missing from its impl", + ); throw_inval!(AlreadyReported(guar.into())); } else { // `find_mir_or_eval_fn` checks that this is a const fn before even calling us, diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 43048dc41d3c2..05731483bdf95 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -217,7 +217,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { // `async` functions cannot be `const fn`. This is checked during AST lowering, so there's // no need to emit duplicate errors here. if self.ccx.is_async() || body.coroutine.is_some() { - tcx.dcx().span_delayed_bug(body.span, "`async` functions cannot be `const fn`"); + tcx.dcx().span_assert_has_errors(body.span, "`async` functions cannot be `const fn`"); return; } @@ -331,7 +331,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { if self.tcx.is_thread_local_static(def_id) { self.tcx .dcx() - .span_delayed_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef`"); + .span_assert_has_errors(span, "tls access is checked in `Rvalue::ThreadLocalRef`"); } self.check_op_spanned(ops::StaticAccess, span) } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 12e7ec15e3292..2ffa03fcbddc6 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -117,7 +117,7 @@ pub fn is_const_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { None if is_parent_const_stable_trait(tcx, def_id) => { // Remove this when `#![feature(const_trait_impl)]` is stabilized, // returning `true` unconditionally. - tcx.dcx().span_delayed_bug( + tcx.dcx().span_assert_has_errors( tcx.def_span(def_id), "trait implementations cannot be const stable yet", ); diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 5ce6a71c4bdd5..dd0964e4eade4 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -118,9 +118,9 @@ impl<'a, 'tcx> CfgChecker<'a, 'tcx> { #[track_caller] fn fail(&self, location: Location, msg: impl AsRef) { let span = self.body.source_info(location).span; - // We use `span_delayed_bug` as we might see broken MIR when other errors have already + // We use `span_assert_has_errors` as we might see broken MIR when other errors have already // occurred. - self.tcx.dcx().span_delayed_bug( + self.tcx.dcx().span_assert_has_errors( span, format!( "broken MIR in {:?} ({}) at {:?}:\n{}", @@ -501,7 +501,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { fn visit_source_scope(&mut self, scope: SourceScope) { if self.body.source_scopes.get(scope).is_none() { - self.tcx.dcx().span_delayed_bug( + self.tcx.dcx().span_assert_has_errors( self.body.span, format!( "broken MIR in {:?} ({}):\ninvalid source scope {:?}", diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 18cf64d937e3b..8c802e5e331fa 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -947,6 +947,28 @@ impl DiagCtxt { pub fn set_must_produce_diag(&self) { self.inner.borrow_mut().must_produce_diag = true; } + + /// Asserts that an error has already been printed. + pub fn assert_has_errors(&self, msg: impl Into) -> ErrorGuaranteed { + if let Some(guar) = self.has_errors() { + guar + } else { + panic!("`assert_has_errors` failed: {:?}", msg.into()); + } + } + + /// Asserts that an error has already been printed. + pub fn span_assert_has_errors( + &self, + sp: impl Into, + msg: impl Into, + ) -> ErrorGuaranteed { + if let Some(guar) = self.has_errors() { + guar + } else { + panic!("`span_assert_has_errors` failed: {:?}, {:?}", msg.into(), sp.into()); + } + } } // This `impl` block contains only the public diagnostic creation/emission API. @@ -1098,14 +1120,14 @@ impl DiagCtxt { self.create_err(err).emit() } - /// Ensures that an error is printed. See `Level::DelayedBug`. + /// Ensures that an error will be emitted later. See `Level::DelayedBug`. // No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing. #[track_caller] pub fn delayed_bug(&self, msg: impl Into) -> ErrorGuaranteed { DiagnosticBuilder::::new(self, DelayedBug, msg).emit() } - /// Ensures that an error is printed. See `Level::DelayedBug`. + /// Ensures that an error will be emitted later. See `Level::DelayedBug`. /// /// Note: this function used to be called `delay_span_bug`. It was renamed /// to match similar functions like `span_err`, `span_warn`, etc. @@ -1566,8 +1588,11 @@ pub enum Level { /// This is a strange one: lets you register an error without emitting it. If compilation ends /// without any other errors occurring, this will be emitted as a bug. Otherwise, it will be - /// silently dropped. I.e. "expect other errors are emitted" semantics. Useful on code paths + /// silently dropped. I.e. "expect more errors will be emitted" semantics. Useful on code paths /// that should only be reached when compiling erroneous code. + /// + /// Note: if you want "expect errors have already been emitted" semantics, use the simpler + /// `DiagCtxt::assert_has_errors` method. DelayedBug, /// A `force-warn` lint warning about the code being compiled. Does not prevent compilation diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index eec86c36aedae..7763e15f6bb27 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -37,7 +37,7 @@ pub(super) fn failed_to_match_macro<'cx>( tracker .cx .dcx() - .span_delayed_bug(sp, "Macro matching returned a success on the second try"); + .span_assert_has_errors(sp, "Macro matching returned a success on the second try"); } if let Some(result) = tracker.result { @@ -154,7 +154,7 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, Success(_) => { // Nonterminal parser recovery might turn failed matches into successful ones, // but for that it must have emitted an error already - self.cx.dcx().span_delayed_bug( + self.cx.dcx().span_assert_has_errors( self.root_span, "should not collect detailed info for successful macro match", ); diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index a001044c3e52d..5d5d97e1d6b68 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -758,7 +758,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // since we should have emitten an error for them earlier, and they will // not be well-formed! if polarity == ty::ImplPolarity::Negative { - self.tcx().dcx().span_delayed_bug( + self.tcx().dcx().span_assert_has_errors( binding.span, "negative trait bounds should not have bindings", ); @@ -1294,7 +1294,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // trait reference. let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else { // A cycle error occurred, most likely. - let guar = tcx.dcx().span_delayed_bug(span, "expected cycle error"); + let guar = tcx.dcx().span_assert_has_errors(span, "expected cycle error"); return Err(guar); }; diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index cbbf560076e27..fd3997d9f28fb 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -329,7 +329,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { false }); if references_self { - let guar = tcx.dcx().span_delayed_bug( + let guar = tcx.dcx().span_assert_has_errors( span, "trait object projection bounds reference `Self`", ); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index b693d7201c15e..941e8527b3746 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -180,7 +180,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b for field in &def.non_enum_variant().fields { let Ok(field_ty) = tcx.try_normalize_erasing_regions(param_env, field.ty(tcx, args)) else { - tcx.dcx().span_delayed_bug(span, "could not normalize field type"); + tcx.dcx().span_assert_has_errors(span, "could not normalize field type"); continue; }; @@ -201,8 +201,10 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b return false; } else if field_ty.needs_drop(tcx, param_env) { // This should never happen. But we can get here e.g. in case of name resolution errors. - tcx.dcx() - .span_delayed_bug(span, "we should never accept maybe-dropping union fields"); + tcx.dcx().span_assert_has_errors( + span, + "we should never accept maybe-dropping union fields", + ); } } } else { @@ -255,7 +257,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) { let item = tcx.hir().expect_item(def_id); let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else { - tcx.dcx().span_delayed_bug(item.span, "expected opaque item"); + tcx.dcx().span_assert_has_errors(item.span, "expected opaque item"); return; }; @@ -380,7 +382,7 @@ fn check_opaque_meets_bounds<'tcx>( Ok(()) => {} Err(ty_err) => { let ty_err = ty_err.to_string(tcx); - return Err(tcx.dcx().span_delayed_bug( + return Err(tcx.dcx().span_assert_has_errors( span, format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"), )); @@ -715,7 +717,8 @@ pub(super) fn check_specialization_validity<'tcx>( if !tcx.is_impl_trait_in_trait(impl_item) { report_forbidden_specialization(tcx, impl_item, parent_impl); } else { - tcx.dcx().delayed_bug(format!("parent item: {parent_impl:?} not marked as default")); + tcx.dcx() + .assert_has_errors(format!("parent item: {parent_impl:?} not marked as default")); } } } @@ -760,7 +763,10 @@ fn check_impl_items_against_trait<'tcx>( tcx.associated_item(trait_item_id) } else { // Checked in `associated_item`. - tcx.dcx().span_delayed_bug(tcx.def_span(impl_item), "missing associated item in trait"); + tcx.dcx().span_assert_has_errors( + tcx.def_span(impl_item), + "missing associated item in trait", + ); continue; }; match ty_impl_item.kind { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 69a02b73a7987..2b5399adcaf75 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -734,7 +734,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( remapped_types.insert(def_id, ty::EarlyBinder::bind(ty)); } Err(err) => { - let reported = tcx.dcx().span_delayed_bug( + let reported = tcx.dcx().span_assert_has_errors( return_span, format!("could not fully resolve: {ty} => {err:?}"), ); @@ -917,7 +917,7 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> { .with_note(format!("hidden type inferred to be `{}`", self.ty)) .emit() } - _ => self.tcx.dcx().delayed_bug("should've been able to remap region"), + _ => self.tcx.dcx().assert_has_errors("should've been able to remap region"), }; return Err(guar); }; @@ -1276,7 +1276,7 @@ fn compare_number_of_generics<'tcx>( // inheriting the generics from will also have mismatched arguments, and // we'll report an error for that instead. Delay a bug for safety, though. if trait_.is_impl_trait_in_trait() { - return Err(tcx.dcx().delayed_bug( + return Err(tcx.dcx().assert_has_errors( "errors comparing numbers of generics of trait/impl functions were not emitted", )); } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index 3d3b21eabb383..bfb696da6b15e 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -154,7 +154,8 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( trait_m_sig.inputs_and_output, )); if !ocx.select_all_or_error().is_empty() { - tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (selection)"); + tcx.dcx() + .assert_has_errors("encountered errors when checking RPITIT refinement (selection)"); return; } let outlives_env = OutlivesEnvironment::with_bounds( @@ -163,12 +164,13 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( ); let errors = infcx.resolve_regions(&outlives_env); if !errors.is_empty() { - tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (regions)"); + tcx.dcx().assert_has_errors("encountered errors when checking RPITIT refinement (regions)"); return; } // Resolve any lifetime variables that may have been introduced during normalization. let Ok((trait_bounds, impl_bounds)) = infcx.fully_resolve((trait_bounds, impl_bounds)) else { - tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (resolution)"); + tcx.dcx() + .assert_has_errors("encountered errors when checking RPITIT refinement (resolution)"); return; }; diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 82a6b6b6f2cb5..3f0e972ac6d76 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -67,7 +67,7 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro // already checked by coherence, but compilation may // not have been terminated. let span = tcx.def_span(drop_impl_did); - let reported = tcx.dcx().span_delayed_bug( + let reported = tcx.dcx().span_assert_has_errors( span, format!("should have been rejected by coherence check: {dtor_self_type}"), ); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index d03b02f028da1..881545c1c0c88 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -294,7 +294,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>, enclosing_id: LocalDefId) { let target_features = self.tcx.asm_target_features(enclosing_id.to_def_id()); let Some(asm_arch) = self.tcx.sess.asm_arch else { - self.tcx.dcx().delayed_bug("target architecture does not support asm"); + self.tcx.dcx().assert_has_errors("target architecture does not support asm"); return; }; for (idx, (op, op_sp)) in asm.operands.iter().enumerate() { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 7f674a1e7e45f..ee19b7cf14f77 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1088,8 +1088,10 @@ fn check_type_defn<'tcx>( let ty = tcx.type_of(variant.tail().did).instantiate_identity(); let ty = tcx.erase_regions(ty); if ty.has_infer() { - tcx.dcx() - .span_delayed_bug(item.span, format!("inference variables in {ty:?}")); + tcx.dcx().span_assert_has_errors( + item.span, + format!("inference variables in {ty:?}"), + ); // Just treat unresolved type expression as if it needs drop. true } else { @@ -1872,7 +1874,7 @@ fn check_variances_for_type_defn<'tcx>( // // if they aren't in the same order, then the user has written invalid code, and already // got an error about it (or I'm wrong about this) - tcx.dcx().span_delayed_bug( + tcx.dcx().span_assert_has_errors( hir_param.span, "hir generics and ty generics in different order", ); diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 45641be52d2f2..e977b9aaff590 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -454,7 +454,7 @@ fn lint_auto_trait_impl<'tcx>( impl_def_id: LocalDefId, ) { if trait_ref.args.len() != 1 { - tcx.dcx().span_delayed_bug( + tcx.dcx().span_assert_has_errors( tcx.def_span(impl_def_id), "auto traits cannot have generic parameters", ); diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs index d217d53587d56..6e0e50054d382 100644 --- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs +++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs @@ -83,7 +83,7 @@ pub(super) fn check_item( (_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative(_)) => { // Reported in AST validation - tcx.dcx().span_delayed_bug(item.span, "unsafe negative impl"); + tcx.dcx().span_assert_has_errors(item.span, "unsafe negative impl"); Ok(()) } (_, _, Unsafety::Normal, hir::ImplPolarity::Negative(_)) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index e8787d159ae12..0d5d143fb1382 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -948,7 +948,7 @@ impl<'tcx> FieldUniquenessCheckContext<'tcx> { // Abort due to errors (there must be an error if an unnamed field // has any type kind other than an anonymous adt or a named adt) ty_kind => { - self.tcx.dcx().span_delayed_bug( + self.tcx.dcx().span_assert_has_errors( field.ty.span, format!("Unexpected TyKind in FieldUniquenessCheckContext::check_field(): {ty_kind:?}"), ); diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 9cc6c16c12639..b4c944cf90c69 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -315,7 +315,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { if is_host_effect { if let Some(idx) = host_effect_index { - tcx.dcx().span_delayed_bug( + tcx.dcx().span_assert_has_errors( param.span, format!("parent also has host effect param? index: {idx}, def: {def_id:?}"), ); diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index c9cf43ddfc887..2dd0b41bad420 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1339,7 +1339,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } } - self.tcx.dcx().span_delayed_bug( + self.tcx.dcx().span_assert_has_errors( lifetime_ref.ident.span, format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,), ); @@ -1473,7 +1473,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } } - self.tcx.dcx().span_delayed_bug( + self.tcx.dcx().span_assert_has_errors( self.tcx.hir().span(hir_id), format!("could not resolve {param_def_id:?}"), ); diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 79cb384c5bded..e378d96dc80b7 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -209,7 +209,7 @@ impl TaitConstraintLocator<'_> { if let Some(hir_sig) = hir_node.fn_sig() && hir_sig.decl.output.get_infer_ret_ty().is_some() { - let guar = self.tcx.dcx().span_delayed_bug( + let guar = self.tcx.dcx().span_assert_has_errors( hir_sig.decl.output.span(), "inferring return types and opaque types do not mix well", ); diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index c072891e2952e..a9e112c855abf 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -79,7 +79,7 @@ fn enforce_impl_params_are_constrained( if impl_self_ty.references_error() { // Don't complain about unconstrained type params when self ty isn't known due to errors. // (#36836) - tcx.dcx().span_delayed_bug( + tcx.dcx().span_assert_has_errors( tcx.def_span(impl_def_id), format!( "potentially unconstrained type parameters weren't evaluated: {impl_self_ty:?}", diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index f21de1609cb7f..dfc2515947eab 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -141,7 +141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Error(_) => { let reported = self .dcx() - .span_delayed_bug(span, format!("`{t:?}` should be sized but is not?")); + .span_assert_has_errors(span, format!("`{t:?}` should be sized but is not?")); return Err(reported); } }) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 19bdeab409bb7..90f10119e2406 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -76,7 +76,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // coercions from ! to `expected`. if ty.is_never() { if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) { - let reported = self.dcx().span_delayed_bug( + let reported = self.dcx().span_assert_has_errors( expr.span, "expression with never type wound up being adjusted", ); @@ -647,7 +647,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Set expectation to error in that case and set tainted // by error (#114529) let coerce_to = opt_coerce_to.unwrap_or_else(|| { - let guar = tcx.dcx().span_delayed_bug( + let guar = tcx.dcx().span_assert_has_errors( expr.span, "illegal break with value found but no error reported", ); @@ -1324,7 +1324,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // permit break with a value [1]. if ctxt.coerce.is_none() && !ctxt.may_break { // [1] - self.dcx().span_delayed_bug(body.span, "no coercion, but loop may not break"); + self.dcx().span_assert_has_errors(body.span, "no coercion, but loop may not break"); } ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| Ty::new_unit(self.tcx)) } @@ -2204,8 +2204,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { kind_name: &str, ) -> ErrorGuaranteed { if variant.is_recovered() { - let guar = - self.dcx().span_delayed_bug(expr.span, "parser recovered but no error was emitted"); + let guar = self + .dcx() + .span_assert_has_errors(expr.span, "parser recovered but no error was emitted"); self.set_tainted_by_errors(guar); return guar; } @@ -2440,7 +2441,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let guar = if field.name == kw::Empty { - self.dcx().span_delayed_bug(field.span, "field name with no name") + self.dcx().span_assert_has_errors(field.span, "field name with no name") } else if self.method_exists(field, base_ty, expr.hir_id, expected.only_has_type(self)) { self.ban_take_value_of_method(expr, base_ty, field) } else if !base_ty.is_primitive_ty() { diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 04fb7bcf4f3b4..e829f952400ef 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -542,7 +542,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // The struct path probably didn't resolve if self.mc.typeck_results.opt_field_index(field.hir_id).is_none() { - self.tcx().dcx().span_delayed_bug(field.span, "couldn't resolve index for field"); + self.tcx() + .dcx() + .span_assert_has_errors(field.span, "couldn't resolve index for field"); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index ec3d4ec66a073..704328b4daace 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1455,7 +1455,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { Ok(ok) => self.register_infer_ok_obligations(ok), Err(_) => { - self.dcx().span_delayed_bug( + self.dcx().span_assert_has_errors( span, format!( "instantiate_value_path: (UFCS) {self_ty:?} was a subtype of {impl_ty:?} but now is not?", diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 65b8505c09098..bd39de138f671 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1333,7 +1333,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let variant = match def { Res::Err => { let guar = - self.dcx().span_delayed_bug(path_span, "`Res::Err` but no error emitted"); + self.dcx().span_assert_has_errors(path_span, "`Res::Err` but no error emitted"); self.set_tainted_by_errors(guar); return Err(guar); } diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 2dee5093e876d..3feeec7ef973f 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -48,7 +48,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let to = normalize(to); trace!(?from, ?to); if from.has_non_region_infer() || to.has_non_region_infer() { - tcx.dcx().span_delayed_bug(span, "argument to transmute has inference variables"); + tcx.dcx().span_assert_has_errors(span, "argument to transmute has inference variables"); return; } // Transmutes that are only changing lifetimes are always ok. diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index fefaf9967253b..e33c792716b8c 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -533,9 +533,10 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { let res = self.typeck_results.qpath_res(qpath, pat_hir_id); let ty = self.typeck_results.node_type(pat_hir_id); let ty::Adt(adt_def, _) = ty.kind() else { - self.tcx() - .dcx() - .span_delayed_bug(span, "struct or tuple struct pattern not applied to an ADT"); + self.tcx().dcx().span_assert_has_errors( + span, + "struct or tuple struct pattern not applied to an ADT", + ); return Err(()); }; @@ -568,9 +569,10 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { match ty.kind() { ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()), _ => { - self.tcx() - .dcx() - .span_delayed_bug(span, "struct or tuple struct pattern not applied to an ADT"); + self.tcx().dcx().span_assert_has_errors( + span, + "struct or tuple struct pattern not applied to an ADT", + ); Err(()) } } @@ -583,7 +585,9 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { match ty.kind() { ty::Tuple(args) => Ok(args.len()), _ => { - self.tcx().dcx().span_delayed_bug(span, "tuple pattern not applied to a tuple"); + self.tcx() + .dcx() + .span_assert_has_errors(span, "tuple pattern not applied to a tuple"); Err(()) } } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index d7edc70bce82e..0d1def8b4792d 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -804,7 +804,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let trait_ref = principal.with_self_ty(self.tcx, self_ty); self.elaborate_bounds(iter::once(trait_ref), |this, new_trait_ref, item| { if new_trait_ref.has_non_region_bound_vars() { - this.dcx().span_delayed_bug( + this.dcx().span_assert_has_errors( this.span, "tried to select method from HRTB with non-lifetime bound vars", ); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 729ce1f00cd8b..52c523f4bab37 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -828,7 +828,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: item_span, .. })) => { - tcx.dcx().span_delayed_bug( + tcx.dcx().span_assert_has_errors( *item_span, "auto trait is invoked with no method error, but no error reported?", ); diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 5026fbe4b8066..b03de5980d8f7 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -900,7 +900,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (res, opt_ty, segments) = path_resolution; match res { Res::Err => { - let e = tcx.dcx().span_delayed_bug(qpath.span(), "`Res::Err` but no error emitted"); + let e = tcx + .dcx() + .span_assert_has_errors(qpath.span(), "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); return Ty::new_error(tcx, e); } @@ -1085,7 +1087,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let variant = match res { Res::Err => { - let e = tcx.dcx().span_delayed_bug(pat.span, "`Res::Err` but no error emitted"); + let e = + tcx.dcx().span_assert_has_errors(pat.span, "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); on_error(e); return Ty::new_error(tcx, e); diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 211109b59417a..67a2f3de89427 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -846,7 +846,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - self.dcx().span_delayed_bug( + self.dcx().span_assert_has_errors( closure_span, format!( "two identical projections: ({:?}, {:?})", diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index d84bce09ecb1e..31422427b3be4 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -222,7 +222,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // When encountering `return [0][0]` outside of a `fn` body we can encounter a base // that isn't in the type table. We assume more relevant errors have already been // emitted, so we delay an ICE if none have. (#64638) - self.tcx().dcx().span_delayed_bug(e.span, format!("bad base: `{base:?}`")); + self.tcx().dcx().span_assert_has_errors(e.span, format!("bad base: `{base:?}`")); } if let Some(base_ty) = base_ty && let ty::Ref(_, base_ty_inner, _) = *base_ty.kind() @@ -317,7 +317,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => { self.tcx() .dcx() - .span_delayed_bug(p.span, format!("unexpected generic param: {p:?}")); + .span_assert_has_errors(p.span, format!("unexpected generic param: {p:?}")); } } } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 99882a42abc38..58a340d65e460 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -191,11 +191,11 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { // // rust-lang/rust#57464: `impl Trait` can leak local // scopes (in manner violating typeck). Therefore, use - // `delayed_bug` to allow type error over an ICE. + // `assert_has_errors` to allow type error over an ICE. canonicalizer .tcx .dcx() - .delayed_bug(format!("unexpected region in query response: `{r:?}`")); + .assert_has_errors(format!("unexpected region in query response: `{r:?}`")); r } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index b953b25d6c4cf..18e15c8c16c9b 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -518,9 +518,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - self.tcx - .dcx() - .span_delayed_bug(self.tcx.def_span(generic_param_scope), "expected region errors") + self.tcx.dcx().span_assert_has_errors( + self.tcx.def_span(generic_param_scope), + "expected region errors", + ) } // This method goes through all the errors and try to group certain types diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 6137506d4a994..46218b5bf5b87 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -803,7 +803,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // Errors in earlier passes can yield error variables without // resolution errors here; delay ICE in favor of those errors. - self.tcx().dcx().span_delayed_bug( + self.tcx().dcx().span_assert_has_errors( self.var_infos[node_idx].origin.span(), format!( "collect_error_for_expanding_node() could not find \ diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 7208f17fb340f..9b6a350d276ac 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -303,7 +303,7 @@ where // ignore this, we presume it will yield an error // later, since if a type variable is not resolved by // this point it never will be - self.tcx.dcx().span_delayed_bug( + self.tcx.dcx().span_assert_has_errors( origin.span(), format!("unresolved inference variable in outlives: {v:?}"), ); diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 24b351988bf69..f93cc52594822 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -177,7 +177,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // this point it never will be self.tcx .dcx() - .delayed_bug(format!("unresolved inference variable in outlives: {v:?}")); + .assert_has_errors(format!("unresolved inference variable in outlives: {v:?}")); // add a bound that never holds VerifyBound::AnyBound(vec![]) } diff --git a/compiler/rustc_infer/src/infer/relate/nll.rs b/compiler/rustc_infer/src/infer/relate/nll.rs index 5e2d2af9b8587..b1e2bc476e3d7 100644 --- a/compiler/rustc_infer/src/infer/relate/nll.rs +++ b/compiler/rustc_infer/src/infer/relate/nll.rs @@ -557,7 +557,7 @@ where match b.kind() { ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => { // Forbid inference variables in the RHS. - self.infcx.dcx().span_delayed_bug( + self.infcx.dcx().span_assert_has_errors( self.delegate.span(), format!("unexpected inference var {b:?}",), ); diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 5ae080d470235..6cf0331458ad5 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -432,7 +432,7 @@ pub fn check_ast_node_inner<'a, T: EarlyLintPass>( // that was not lint-checked (perhaps it doesn't exist?). This is a bug. for (id, lints) in cx.context.buffered.map { for early_lint in lints { - sess.dcx().span_delayed_bug( + sess.dcx().span_assert_has_errors( early_lint.span, format!( "failed to process buffered lint here (dummy = {})", diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index afb6937b43b94..8bb06168265ac 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -564,7 +564,8 @@ impl<'tcx> TyCtxt<'tcx> { |span, def_id| { // The API could be uncallable for other reasons, for example when a private module // was referenced. - self.dcx().span_delayed_bug(span, format!("encountered unmarked API: {def_id:?}")); + self.dcx() + .span_assert_has_errors(span, format!("encountered unmarked API: {def_id:?}")); }, ) } diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 0da3524e05564..0bdacbf1b4b7e 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -198,7 +198,7 @@ pub struct LitToConstInput<'tcx> { #[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)] pub enum LitToConstError { /// The literal's inferred type did not match the expected `ty` in the input. - /// This is used for graceful error handling (`span_delayed_bug`) in + /// This is used for graceful error handling (`span_assert_has_errors`) in /// type checking (`Const::from_anon_const`). TypeError, Reported(ErrorGuaranteed), diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 8d88488e1675d..d720f41905010 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -553,7 +553,7 @@ macro_rules! define_feedable { // We have an inconsistency. This can happen if one of the two // results is tainted by errors. In this case, delay a bug to // ensure compilation is doomed, and keep the `old` value. - tcx.dcx().delayed_bug(format!( + tcx.dcx().assert_has_errors(format!( "Trying to feed an already recorded value for query {} key={key:?}:\n\ old value: {old:?}\nnew value: {value:?}", stringify!($name), diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index d07a53ee6794d..058b7c98eb7aa 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -498,7 +498,7 @@ impl<'tcx> AdtDef<'tcx> { ErrorHandled::Reported(..) => "enum discriminant evaluation failed", ErrorHandled::TooGeneric(..) => "enum discriminant depends on generics", }; - tcx.dcx().span_delayed_bug(tcx.def_span(expr_did), msg); + tcx.dcx().span_assert_has_errors(tcx.def_span(expr_did), msg); None } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index bd86c1c284e6e..3af2978c4f1ea 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -755,7 +755,7 @@ impl<'tcx> TyCtxt<'tcx> { { Bound::Included(a.get()) } else { - self.dcx().span_delayed_bug( + self.dcx().span_assert_has_errors( attr.span, "invalid rustc_layout_scalar_valid_range attribute", ); diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 8d8d06b7c0b7f..26eab6ee9bf0b 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -283,8 +283,8 @@ pub struct LayoutCx<'tcx, C> { impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> { type TargetDataLayoutRef = &'tcx TargetDataLayout; - fn delayed_bug(&self, txt: String) { - self.tcx.dcx().delayed_bug(txt); + fn assert_has_errors(&self, txt: String) { + self.tcx.dcx().assert_has_errors(txt); } fn current_data_layout(&self) -> Self::TargetDataLayoutRef { diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index a03ee78a29a58..e52b783273648 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -410,7 +410,7 @@ impl<'tcx> TypeckResults<'tcx> { pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option { self.pat_binding_modes().get(id).copied().or_else(|| { - s.dcx().span_delayed_bug(sp, "missing binding mode"); + s.dcx().span_assert_has_errors(sp, "missing binding mode"); None }) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c674a868d9fa2..ff8eb6ae83ef6 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -361,8 +361,10 @@ impl<'tcx> TyCtxt<'tcx> { } let Some(item_id) = self.associated_item_def_ids(impl_did).first() else { - self.dcx() - .span_delayed_bug(self.def_span(impl_did), "Drop impl without drop function"); + self.dcx().span_assert_has_errors( + self.def_span(impl_did), + "Drop impl without drop function", + ); return; }; diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 6636f75d99811..966d4afb3b669 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -110,15 +110,15 @@ fn lit_to_mir_constant<'tcx>( let LitToConstInput { lit, ty, neg } = lit_input; let trunc = |n| { let param_ty = ty::ParamEnv::reveal_all().and(ty); - let width = - tcx.layout_of(param_ty) - .map_err(|_| { - LitToConstError::Reported(tcx.dcx().delayed_bug(format!( - "couldn't compute width of literal: {:?}", - lit_input.lit - ))) - })? - .size; + let width = tcx + .layout_of(param_ty) + .map_err(|_| { + LitToConstError::Reported(tcx.dcx().assert_has_errors(format!( + "couldn't compute width of literal: {:?}", + lit_input.lit + ))) + })? + .size; trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); let result = width.truncate(n); trace!("trunc result: {}", result); @@ -157,16 +157,16 @@ fn lit_to_mir_constant<'tcx>( } (ast::LitKind::Float(n, _), ty::Float(fty)) => parse_float_into_constval(*n, *fty, neg) .ok_or_else(|| { - LitToConstError::Reported( - tcx.dcx() - .delayed_bug(format!("couldn't parse float literal: {:?}", lit_input.lit)), - ) + LitToConstError::Reported(tcx.dcx().assert_has_errors(format!( + "couldn't parse float literal: {:?}", + lit_input.lit + ))) })?, (ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)), (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)), (ast::LitKind::Err, _) => { return Err(LitToConstError::Reported( - tcx.dcx().delayed_bug("encountered LitKind::Err during mir build"), + tcx.dcx().assert_has_errors("encountered LitKind::Err during mir build"), )); } _ => return Err(LitToConstError::TypeError), diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 04740a9629152..77e6bcc87ef8c 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -657,7 +657,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } else { let Some(drops) = self.scopes.breakable_scopes[break_index].continue_drops.as_mut() else { - self.tcx.dcx().span_delayed_bug( + self.tcx.dcx().span_assert_has_errors( source_info.span, "unlabelled `continue` within labelled block", ); diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 8688c58906331..4bd9c70d6e8b0 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -476,7 +476,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { if let Some((assigned_ty, assignment_span)) = self.assignment_info { if assigned_ty.needs_drop(self.tcx, self.param_env) { // This would be unsafe, but should be outright impossible since we reject such unions. - self.tcx.dcx().span_delayed_bug(assignment_span, format!("union fields that need dropping should be impossible: {assigned_ty}")); + self.tcx.dcx().span_assert_has_errors(assignment_span, format!("union fields that need dropping should be impossible: {assigned_ty}")); } } else { self.requires_unsafe(expr.span, AccessToUnionField); diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 71aebd13003b4..dfee6e61c5674 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -12,15 +12,15 @@ pub(crate) fn lit_to_const<'tcx>( let trunc = |n| { let param_ty = ParamEnv::reveal_all().and(ty); - let width = - tcx.layout_of(param_ty) - .map_err(|_| { - LitToConstError::Reported(tcx.dcx().delayed_bug(format!( - "couldn't compute width of literal: {:?}", - lit_input.lit - ))) - })? - .size; + let width = tcx + .layout_of(param_ty) + .map_err(|_| { + LitToConstError::Reported(tcx.dcx().assert_has_errors(format!( + "couldn't compute width of literal: {:?}", + lit_input.lit + ))) + })? + .size; trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); let result = width.truncate(n); trace!("trunc result: {}", result); @@ -59,21 +59,20 @@ pub(crate) fn lit_to_const<'tcx>( } (ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()), (ast::LitKind::Float(n, _), ty::Float(fty)) => { - let bits = - parse_float_into_scalar(*n, *fty, neg) - .ok_or_else(|| { - LitToConstError::Reported(tcx.dcx().delayed_bug(format!( - "couldn't parse float literal: {:?}", - lit_input.lit - ))) - })? - .assert_int(); + let bits = parse_float_into_scalar(*n, *fty, neg) + .ok_or_else(|| { + LitToConstError::Reported(tcx.dcx().assert_has_errors(format!( + "couldn't parse float literal: {:?}", + lit_input.lit + ))) + })? + .assert_int(); ty::ValTree::from_scalar_int(bits) } (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()), (ast::LitKind::Err, _) => { return Err(LitToConstError::Reported( - tcx.dcx().delayed_bug("encountered LitKind::Err during mir build"), + tcx.dcx().assert_has_errors("encountered LitKind::Err during mir build"), )); } _ => return Err(LitToConstError::TypeError), diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 1a5cf13e28978..b63f9a98c6bf1 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -105,7 +105,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let msg = format!( "found bad range pattern endpoint `{expr:?}` outside of error recovery" ); - return Err(self.tcx.dcx().span_delayed_bug(expr.span, msg)); + return Err(self.tcx.dcx().span_assert_has_errors(expr.span, msg)); }; Ok((Some(PatRangeBoundary::Finite(value)), ascr, inline_const)) } @@ -175,7 +175,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { ) -> Result, ErrorGuaranteed> { if lo_expr.is_none() && hi_expr.is_none() { let msg = "found twice-open range pattern (`..`) outside of error recovery"; - return Err(self.tcx.dcx().span_delayed_bug(span, msg)); + return Err(self.tcx.dcx().span_assert_has_errors(span, msg)); } let (lo, lo_ascr, lo_inline) = self.lower_pattern_range_endpoint(lo_expr)?; diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index fbb626953835e..3f1a56509e761 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -244,7 +244,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { let assigned_ty = place.ty(&self.body.local_decls, self.tcx).ty; if assigned_ty.needs_drop(self.tcx, self.param_env) { // This would be unsafe, but should be outright impossible since we reject such unions. - self.tcx.dcx().span_delayed_bug( + self.tcx.dcx().span_assert_has_errors( self.source_info.span, format!("union fields that need dropping should be impossible: {assigned_ty}") ); diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index a0851aa557b86..e2949568a8332 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1615,7 +1615,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform { (args.discr_ty(tcx), coroutine_kind.movability() == hir::Movability::Movable) } _ => { - tcx.dcx().span_delayed_bug( + tcx.dcx().span_assert_has_errors( body.span, format!("unexpected coroutine type {coroutine_ty}"), ); diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 8575f552f0ae7..fe447a65edea5 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -315,7 +315,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { self.init_data.seek_before(self.body.terminator_loc(bb)); let (_maybe_live, maybe_dead) = self.init_data.maybe_live_dead(parent); if maybe_dead { - self.tcx.dcx().span_delayed_bug( + self.tcx.dcx().span_assert_has_errors( terminator.source_info.span, format!( "drop of untracked, uninitialized value {bb:?}, place {place:?} ({path:?})" @@ -380,7 +380,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { LookupResult::Parent(None) => {} LookupResult::Parent(Some(_)) => { if !replace { - self.tcx.dcx().span_delayed_bug( + self.tcx.dcx().span_assert_has_errors( terminator.source_info.span, format!("drop of untracked value {bb:?}"), ); diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 9f30f2836f195..d156fb3dfb12d 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -265,7 +265,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { let body = &tcx.mir_const(def).borrow(); if body.return_ty().references_error() { - tcx.dcx().span_delayed_bug(body.span, "mir_const_qualif: MIR had errors"); + tcx.dcx().span_assert_has_errors(body.span, "mir_const_qualif: MIR had errors"); return Default::default(); } diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 2307f4cfffae6..21fa69af5f715 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -266,7 +266,8 @@ impl<'a> Parser<'a> { if let Some(attr_range) = self.capture_state.inner_attr_ranges.remove(&inner_attr.id) { inner_attr_replace_ranges.push(attr_range); } else { - self.dcx().span_delayed_bug(inner_attr.span, "Missing token range for attribute"); + self.dcx() + .span_assert_has_errors(inner_attr.span, "Missing token range for attribute"); } } diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 02f56ecb10b57..343b668189019 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -31,7 +31,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { if !errors.is_empty() { let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2); - tcx.dcx().delayed_bug(message); + tcx.dcx().assert_has_errors(message); } } } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 3a8dc3775206c..737b30b477a19 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -561,7 +561,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { match self.successors[ln] { Some(successor) => self.assigned_on_entry(successor, var), None => { - self.ir.tcx.dcx().delayed_bug("no successor"); + self.ir.tcx.dcx().assert_has_errors("no successor"); true } } @@ -970,7 +970,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // Now that we know the label we're going to, // look it up in the continue loop nodes table self.cont_ln.get(&sc).cloned().unwrap_or_else(|| { - self.ir.tcx.dcx().span_delayed_bug(expr.span, "continue to unknown label"); + self.ir + .tcx + .dcx() + .span_assert_has_errors(expr.span, "continue to unknown label"); self.ir.add_live_node(ErrNode) }) } diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 9158ba00901c6..c97724b13fa42 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -431,7 +431,7 @@ where // We have an inconsistency. This can happen if one of the two // results is tainted by errors. In this case, delay a bug to // ensure compilation is doomed. - qcx.dep_context().sess().dcx().delayed_bug(format!( + qcx.dep_context().sess().dcx().assert_has_errors(format!( "Computed query value for {:?}({:?}) is inconsistent with fed value,\n\ computed={:#?}\nfed={:#?}", query.dep_kind(), diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index e47f2bdd4d2b1..a14e0ef5ef275 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1200,7 +1200,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } }; self.report_error(span, error); - self.dcx().span_delayed_bug(span, CG_BUG_STR); + self.dcx().span_assert_has_errors(span, CG_BUG_STR); } return Res::Err; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 6bd221ff05874..9fd8cc79a8f43 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3684,7 +3684,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { Res::SelfCtor(_) => { // We resolve `Self` in pattern position as an ident sometimes during recovery, // so delay a bug instead of ICEing. - self.r.dcx().span_delayed_bug( + self.r.dcx().span_assert_has_errors( ident.span, "unexpected `SelfCtor` in pattern, expected identifier" ); diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 733c415ead50a..2a36962dc9c35 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{fast_reject, TypeFoldable}; use rustc_middle::ty::{ToPredicate, TypeVisitableExt}; -use rustc_span::{ErrorGuaranteed, DUMMY_SP}; +use rustc_span::ErrorGuaranteed; use std::fmt::Debug; pub(super) mod structural_traits; @@ -611,10 +611,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty), ty::Alias(ty::Inherent | ty::Weak, _) => { - self.tcx().sess.dcx().span_delayed_bug( - DUMMY_SP, - format!("could not normalize {self_ty}, it is not WF"), - ); + self.tcx() + .sess + .dcx() + .delayed_bug(format!("could not normalize {self_ty}, it is not WF")); return; } }; diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index d177109c42046..f6adb2f7676be 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -286,7 +286,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - ecx.tcx().dcx().span_delayed_bug( + ecx.tcx().dcx().span_assert_has_errors( ecx.tcx().def_span(goal.predicate.def_id()), "associated types not allowed on auto traits", ); diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 522c645253a21..c36315cf5945b 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -65,7 +65,7 @@ pub fn is_const_evaluatable<'tcx>( // FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete, but // currently it is not possible to evaluate `ConstKind::Expr` so we are unable to tell if it // is evaluatable or not. For now we just ICE until this is implemented. - Err(NotConstEvaluatable::Error(tcx.dcx().span_delayed_bug( + Err(NotConstEvaluatable::Error(tcx.dcx().span_assert_has_errors( span, "evaluating `ConstKind::Expr` is not currently supported", ))) @@ -138,7 +138,7 @@ pub fn is_const_evaluatable<'tcx>( } else if uv.has_non_region_param() { NotConstEvaluatable::MentionsParam } else { - let guar = infcx.dcx().span_delayed_bug( + let guar = infcx.dcx().span_assert_has_errors( span, "Missing value for constant, but no error reported?", ); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index f0773fd1671e2..9ac87b8475d15 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -662,7 +662,8 @@ impl<'tcx> OnUnimplementedDirective { Ok(None) } else { - let reported = tcx.dcx().delayed_bug("of_item: neither meta_item_list nor value_str"); + let reported = + tcx.dcx().assert_has_errors("of_item: neither meta_item_list nor value_str"); return Err(reported); }; debug!("of_item({:?}) = {:?}", item_def_id, result); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index c5ee03916825c..03128f85f9a2c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -519,7 +519,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_ref, span, ) { - GetSafeTransmuteErrorAndReason::Silent => return self.dcx().span_delayed_bug(span, "silent safe transmute error"), + GetSafeTransmuteErrorAndReason::Silent => return self.dcx().span_assert_has_errors(span, "silent safe transmute error"), GetSafeTransmuteErrorAndReason::Error { err_msg, safe_transmute_explanation, @@ -3481,7 +3481,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { expected_trait_ref.self_ty().error_reported()?; let Some(found_trait_ty) = found_trait_ref.self_ty().no_bound_vars() else { - return Err(self.dcx().delayed_bug("bound vars outside binder")); + return Err(self.dcx().assert_has_errors("bound vars outside binder")); }; let found_did = match *found_trait_ty.kind() { @@ -3495,7 +3495,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if !self.reported_signature_mismatch.borrow_mut().insert((span, found_span)) { // We check closures twice, with obligations flowing in different directions, // but we want to complain about them only once. - return Err(self.dcx().span_delayed_bug(span, "already_reported")); + return Err(self.dcx().span_assert_has_errors(span, "already_reported")); } let mut not_tupled = false; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 7caaccab63bc1..ffbdd45ad904b 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -216,7 +216,7 @@ fn do_normalize_predicates<'tcx>( // the normalized predicates. let errors = infcx.resolve_regions(&outlives_env); if !errors.is_empty() { - tcx.dcx().span_delayed_bug( + tcx.dcx().span_assert_has_errors( span, format!("failed region resolution while normalizing {elaborated_env:?}: {errors:?}"), ); diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 29a4a078fe03f..730a7a9f557d5 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -508,7 +508,7 @@ fn virtual_call_violations_for_method<'tcx>( Ok(layout) => Some(layout.abi), Err(err) => { // #78372 - tcx.dcx().span_delayed_bug( + tcx.dcx().span_assert_has_errors( tcx.def_span(method.def_id), format!("error: {err}\n while computing layout for type {ty:?}"), ); @@ -542,7 +542,7 @@ fn virtual_call_violations_for_method<'tcx>( match abi_of_ty(trait_object_receiver) { Some(Abi::ScalarPair(..)) => (), abi => { - tcx.dcx().span_delayed_bug( + tcx.dcx().span_assert_has_errors( tcx.def_span(method.def_id), format!( "receiver when `Self = {trait_object_ty}` should have a ScalarPair ABI; found {abi:?}" @@ -594,7 +594,8 @@ fn virtual_call_violations_for_method<'tcx>( // would already have reported an error at the definition of the // auto trait. if pred_trait_ref.args.len() != 1 { - tcx.dcx().span_delayed_bug(span, "auto traits cannot have generic parameters"); + tcx.dcx() + .span_assert_has_errors(span, "auto traits cannot have generic parameters"); } return false; } diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 52631d4353bfa..596a9504abb69 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -120,7 +120,7 @@ fn implied_outlives_bounds<'a, 'tcx>( let errors = ocx.select_all_or_error(); if !errors.is_empty() { - infcx.dcx().span_delayed_bug( + infcx.dcx().span_assert_has_errors( span, "implied_outlives_bounds failed to solve obligations from instantiation", ); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 049877bc5fed4..2b4e8e6c7a15a 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1471,7 +1471,7 @@ pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>( match selcx.infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, impl_ty, self_ty) { Ok(mut ok) => obligations.append(&mut ok.obligations), Err(_) => { - tcx.dcx().span_delayed_bug( + tcx.dcx().span_assert_has_errors( cause.span, format!( "{self_ty:?} was a subtype of {impl_ty:?} during selection but now it is not" @@ -2016,7 +2016,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) | ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => { // These traits have no associated types. - selcx.tcx().dcx().span_delayed_bug( + selcx.tcx().dcx().span_assert_has_errors( obligation.cause.span, format!("Cannot project an associated type from `{impl_source:?}`"), ); diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index d533e69a4fa7f..74684b03be985 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -82,7 +82,7 @@ where let value = infcx.commit_if_ok(|_| { let ocx = ObligationCtxt::new(infcx); let value = op(&ocx).map_err(|_| { - infcx.dcx().span_delayed_bug(span, format!("error performing operation: {name}")) + infcx.dcx().span_assert_has_errors(span, format!("error performing operation: {name}")) })?; let errors = ocx.select_all_or_error(); if errors.is_empty() { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index fb09f094d37ae..e34836a1cc571 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -190,7 +190,7 @@ where } } if !progress { - return Err(infcx.dcx().span_delayed_bug( + return Err(infcx.dcx().span_assert_has_errors( span, format!("ambiguity processing {obligations:?} from {self:?}"), )); diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 73df1be6b552a..3bc0e66027eb8 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -459,7 +459,8 @@ fn report_conflicting_impls<'tcx>( decorate(tcx, &overlap, impl_span, &mut err); err.emit() } else { - tcx.dcx().span_delayed_bug(impl_span, "impl should have failed the orphan check") + tcx.dcx() + .span_assert_has_errors(impl_span, "impl should have failed the orphan check") }; Err(reported) } diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 89459f377dd2b..ff5e6f8cd3ae8 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -138,7 +138,9 @@ impl<'tcx> TypeVisitor> for Search<'tcx> { bug!("unexpected type during structural-match checking: {:?}", ty); } ty::Error(_) => { - self.tcx.dcx().span_delayed_bug(self.span, "ty::Error in structural-match check"); + self.tcx + .dcx() + .span_assert_has_errors(self.span, "ty::Error in structural-match check"); // We still want to check other types after encountering an error, // as this may still emit relevant errors. return ControlFlow::Continue(()); diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 7fa416197b35f..fb9fc8c3ab920 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -80,7 +80,7 @@ fn resolve_associated_item<'tcx>( let vtbl = match tcx.codegen_select_candidate((param_env, trait_ref)) { Ok(vtbl) => vtbl, Err(CodegenObligationError::Ambiguity) => { - let reported = tcx.dcx().span_delayed_bug( + let reported = tcx.dcx().span_assert_has_errors( tcx.def_span(trait_item_id), format!( "encountered ambiguity selecting `{trait_ref:?}` during codegen, presuming due to \ @@ -172,7 +172,7 @@ fn resolve_associated_item<'tcx>( // Any final impl is required to define all associated items. if !leaf_def.item.defaultness(tcx).has_value() { - let guard = tcx.dcx().span_delayed_bug( + let guard = tcx.dcx().span_assert_has_errors( tcx.def_span(leaf_def.item.def_id), "missing value for assoc item in impl", ); diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 96f8148bf7204..4b0f014747a31 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -90,7 +90,7 @@ fn univariant_uninterned<'tcx>( let dl = cx.data_layout(); let pack = repr.pack; if pack.is_some() && repr.align.is_some() { - cx.tcx.dcx().delayed_bug("struct cannot be packed and aligned"); + cx.tcx.dcx().assert_has_errors("struct cannot be packed and aligned"); return Err(cx.tcx.arena.alloc(LayoutError::Unknown(ty))); } @@ -354,7 +354,8 @@ fn layout_of_uncached<'tcx>( ty::Adt(def, args) if def.repr().simd() => { if !def.is_struct() { // Should have yielded E0517 by now. - tcx.dcx().delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct"); + tcx.dcx() + .assert_has_errors("#[repr(simd)] was applied to an ADT that is not a struct"); return Err(error(cx, LayoutError::Unknown(ty))); } @@ -381,7 +382,7 @@ fn layout_of_uncached<'tcx>( // (should be caught by typeck) for fi in fields { if fi.ty(tcx, args) != f0_ty { - tcx.dcx().delayed_bug( + tcx.dcx().assert_has_errors( "#[repr(simd)] was applied to an ADT with heterogeneous field type", ); return Err(error(cx, LayoutError::Unknown(ty))); @@ -491,7 +492,7 @@ fn layout_of_uncached<'tcx>( if def.is_union() { if def.repr().pack.is_some() && def.repr().align.is_some() { - cx.tcx.dcx().span_delayed_bug( + cx.tcx.dcx().span_assert_has_errors( tcx.def_span(def.did()), "union cannot be packed and aligned", ); diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 329cf32cad5ea..2be5dba941c93 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -241,7 +241,7 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { .instantiate(self.tcx, impl_args) .visit_with(self); } else { - self.tcx.dcx().span_delayed_bug( + self.tcx.dcx().span_assert_has_errors( self.tcx.def_span(assoc.def_id), "item had incorrect args", ); @@ -337,7 +337,7 @@ impl<'tcx> TypeVisitor> for ImplTraitInAssocTypeCollector<'tcx> { .instantiate(self.0.tcx, impl_args) .visit_with(self); } else { - self.0.tcx.dcx().span_delayed_bug( + self.0.tcx.dcx().span_assert_has_errors( self.0.tcx.def_span(assoc.def_id), "item had incorrect args", ); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index be1c8d9094bfb..9ff78493cfa3f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -114,7 +114,7 @@ struct LayoutCx<'a> { impl<'a> LayoutCalculator for LayoutCx<'a> { type TargetDataLayoutRef = &'a TargetDataLayout; - fn delayed_bug(&self, txt: String) { + fn assert_has_errors(&self, txt: String) { never!("{}", txt); }