diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 103c7ed8ef701..dd222485daf2c 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -299,8 +299,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { if errors.is_empty() { definition_ty } else { - infcx.err_ctxt().report_fulfillment_errors(&errors, None); - self.tcx.ty_error() + let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None); + self.tcx.ty_error_with_guaranteed(reported) } } } 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 02909592637d8..14cfc3613bf0c 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -247,12 +247,13 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { .and(type_op::normalize::Normalize::new(ty)) .fully_perform(self.infcx) .unwrap_or_else(|_| { - self.infcx + let reported = self + .infcx .tcx .sess .delay_span_bug(span, &format!("failed to normalize {:?}", ty)); TypeOpOutput { - output: self.infcx.tcx.ty_error(), + output: self.infcx.tcx.ty_error_with_guaranteed(reported), constraints: None, error_info: None, } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 50af229baaaed..9c1d0bb8b2357 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -233,11 +233,11 @@ 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() { - infcx.tcx.sess.delay_span_bug( + let reported = infcx.tcx.sess.delay_span_bug( decl.hidden_type.span, &format!("could not resolve {:#?}", hidden_type.ty.kind()), ); - hidden_type.ty = infcx.tcx.ty_error(); + hidden_type.ty = infcx.tcx.ty_error_with_guaranteed(reported); } (opaque_type_key, (hidden_type, decl.origin)) diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index ecf8570e81f71..730061fca9936 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -482,9 +482,9 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { /// In the meantime, though, callsites are required to deal with the "bug" /// locally in whichever way makes the most sense. #[track_caller] - pub fn delay_as_bug(&mut self) { + pub fn delay_as_bug(&mut self) -> G { self.downgrade_to_delayed_bug(); - self.emit(); + self.emit() } forward!( diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 8b1cc50a3a1f9..2665813478c2c 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1201,7 +1201,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { (_, _) => { let got = if let Some(_) = term.ty() { "type" } else { "constant" }; let expected = def_kind.descr(assoc_item_def_id); - tcx.sess + let reported = tcx + .sess .struct_span_err( binding.span, &format!("expected {expected} bound, found {got}"), @@ -1212,11 +1213,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) .emit(); term = match def_kind { - hir::def::DefKind::AssocTy => tcx.ty_error().into(), + hir::def::DefKind::AssocTy => { + tcx.ty_error_with_guaranteed(reported).into() + } hir::def::DefKind::AssocConst => tcx - .const_error( + .const_error_with_guaranteed( tcx.bound_type_of(assoc_item_def_id) .subst(tcx, projection_ty.skip_binder().substs), + reported, ) .into(), _ => unreachable!(), @@ -1334,8 +1338,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .map(|&(trait_ref, _, _)| trait_ref.def_id()) .find(|&trait_ref| tcx.is_trait_alias(trait_ref)) .map(|trait_ref| tcx.def_span(trait_ref)); - tcx.sess.emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }); - return tcx.ty_error(); + let reported = + tcx.sess.emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }); + return tcx.ty_error_with_guaranteed(reported); } // Check that there are no gross object safety violations; @@ -1345,14 +1350,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let object_safety_violations = astconv_object_safety_violations(tcx, item.trait_ref().def_id()); if !object_safety_violations.is_empty() { - report_object_safety_error( + let reported = report_object_safety_error( tcx, span, item.trait_ref().def_id(), &object_safety_violations, ) .emit(); - return tcx.ty_error(); + return tcx.ty_error_with_guaranteed(reported); } } @@ -2112,13 +2117,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "Type" }; - self.report_ambiguous_associated_type( + let reported = self.report_ambiguous_associated_type( span, type_name, &path_str, item_segment.ident.name, ); - return tcx.ty_error(); + return tcx.ty_error_with_guaranteed(reported) }; debug!("qpath_to_ty: self_type={:?}", self_ty); @@ -2560,8 +2565,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { { err.span_note(impl_.self_ty.span, "not a concrete type"); } - err.emit(); - tcx.ty_error() + tcx.ty_error_with_guaranteed(err.emit()) } else { self.normalize_ty(span, ty) } diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index 0e8ac17fb71b1..660c56ee8b011 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -611,11 +611,11 @@ pub fn collect_trait_impl_trait_tys<'tcx>( collected_tys.insert(def_id, ty); } Err(err) => { - tcx.sess.delay_span_bug( + let reported = tcx.sess.delay_span_bug( return_span, format!("could not fully resolve: {ty} => {err:?}"), ); - collected_tys.insert(def_id, tcx.ty_error()); + collected_tys.insert(def_id, tcx.ty_error_with_guaranteed(reported)); } } } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 25faacadf3d0c..4bca16c3a1cce 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -512,8 +512,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> { } _ => {} } - err.emit(); - self.tcx().ty_error() + self.tcx().ty_error_with_guaranteed(err.emit()) } } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index c29a645eb4a88..2402495c2e4a6 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -698,7 +698,7 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T } let Some(hidden) = locator.found else { - tcx.sess.emit_err(UnconstrainedOpaqueType { + let reported = tcx.sess.emit_err(UnconstrainedOpaqueType { span: tcx.def_span(def_id), name: tcx.item_name(tcx.local_parent(def_id).to_def_id()), what: match tcx.hir().get(scope) { @@ -708,7 +708,7 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T _ => "item", }, }); - return tcx.ty_error(); + return tcx.ty_error_with_guaranteed(reported); }; // Only check against typeck if we didn't already error diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 25306ebf35679..4d8ab2c1c7ad9 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1639,9 +1639,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { if visitor.ret_exprs.len() > 0 && let Some(expr) = expression { self.note_unreachable_loop_return(&mut err, &expr, &visitor.ret_exprs); } - err.emit_unless(unsized_return); + let reported = err.emit_unless(unsized_return); - self.final_ty = Some(fcx.tcx.ty_error()); + self.final_ty = Some(fcx.tcx.ty_error_with_guaranteed(reported)); } } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 89b5e5161a9c2..43669489e69bb 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -80,14 +80,14 @@ 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) { - self.tcx().sess.delay_span_bug( + let reported = self.tcx().sess.delay_span_bug( expr.span, "expression with never type wound up being adjusted", ); return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &adjustments[..] { target.to_owned() } else { - self.tcx().ty_error() + self.tcx().ty_error_with_guaranteed(reported) }; } @@ -396,8 +396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } - err.emit(); - oprnd_t = tcx.ty_error(); + oprnd_t = tcx.ty_error_with_guaranteed(err.emit()); } } hir::UnOp::Not => { @@ -1097,12 +1096,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the assignment expression itself is ill-formed, don't // bother emitting another error - if lhs_ty.references_error() || rhs_ty.references_error() { - err.delay_as_bug() - } else { - err.emit(); - } - return self.tcx.ty_error(); + let reported = err.emit_unless(lhs_ty.references_error() || rhs_ty.references_error()); + return self.tcx.ty_error_with_guaranteed(reported); } let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace); @@ -2777,8 +2772,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } } - err.emit(); - self.tcx.ty_error() + let reported = err.emit(); + self.tcx.ty_error_with_guaranteed(reported) } } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 35323137e2d5a..6ed7a93d46332 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1212,9 +1212,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - err.emit(); - - return (tcx.ty_error(), res); + let reported = err.emit(); + return (tcx.ty_error_with_guaranteed(reported), res); } } } else { diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index c3bcbcc993b7c..38b3dd218a971 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -529,8 +529,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - err.emit(); - self.tcx.ty_error() + let reported = err.emit(); + self.tcx.ty_error_with_guaranteed(reported) } }; diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index ea90da4a6dc35..c248deb892b1d 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1278,12 +1278,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let element_tys = tcx.mk_type_list(element_tys_iter); let pat_ty = tcx.mk_ty(ty::Tuple(element_tys)); if let Some(mut err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, ti) { - err.emit(); + let reported = err.emit(); // Walk subpatterns with an expected type of `err` in this case to silence // further errors being emitted when using the bindings. #50333 - let element_tys_iter = (0..max_len).map(|_| tcx.ty_error()); + let element_tys_iter = (0..max_len).map(|_| tcx.ty_error_with_guaranteed(reported)); for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { - self.check_pat(elem, tcx.ty_error(), def_bm, ti); + self.check_pat(elem, tcx.ty_error_with_guaranteed(reported), def_bm, ti); } tcx.mk_tup(element_tys_iter) } else { diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index ba8cf6926f30b..952ea14887f7b 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -90,8 +90,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); } - err.emit(); - Some((self.tcx.ty_error(), self.tcx.ty_error())) + let reported = err.emit(); + Some(( + self.tcx.ty_error_with_guaranteed(reported), + self.tcx.ty_error_with_guaranteed(reported), + )) } /// To type-check `base_expr[index_expr]`, we progressively autoderef diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index fc706b890d5fb..50eece3011280 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1283,6 +1283,12 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed` + #[track_caller] + pub fn ty_error_with_guaranteed(self, reported: ErrorGuaranteed) -> Ty<'tcx> { + self.mk_ty(Error(reported)) + } + /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used. #[track_caller] pub fn ty_error(self) -> Ty<'tcx> { @@ -1297,6 +1303,16 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ty(Error(reported)) } + /// Like [TyCtxt::ty_error] but for constants, with current `ErrorGuaranteed` + #[track_caller] + pub fn const_error_with_guaranteed( + self, + ty: Ty<'tcx>, + reported: ErrorGuaranteed, + ) -> Const<'tcx> { + self.mk_const(ty::ConstKind::Error(reported), ty) + } + /// Like [TyCtxt::ty_error] but for constants. #[track_caller] pub fn const_error(self, ty: Ty<'tcx>) -> Const<'tcx> { diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index f0e9f990a8115..5e366ef703f25 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -97,7 +97,11 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { } fn error_reported(&self) -> Result<(), ErrorGuaranteed> { if self.references_error() { - Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()) + if let Some(reported) = ty::tls::with(|tcx| tcx.sess.has_errors()) { + Err(reported) + } else { + bug!("expect tcx.sess.has_errors return true"); + } } else { Ok(()) }