Skip to content

Add 'ty_error_with_guaranteed' and 'const_error_with_guaranteed' #103928

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
@@ -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)
}
}
}
Original file line number Diff line number Diff line change
@@ -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,
}
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
@@ -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))
4 changes: 2 additions & 2 deletions compiler/rustc_errors/src/diagnostic_builder.rs
Original file line number Diff line number Diff line change
@@ -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!(
26 changes: 15 additions & 11 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
@@ -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)
}
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/check/compare_method.rs
Original file line number Diff line number Diff line change
@@ -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));
}
}
}
3 changes: 1 addition & 2 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
@@ -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())
}
}

4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
@@ -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));
}
}
}
19 changes: 7 additions & 12 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
@@ -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)
}
}
}
5 changes: 2 additions & 3 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
@@ -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 {
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/op.rs
Original file line number Diff line number Diff line change
@@ -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)
}
};

6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
@@ -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 {
7 changes: 5 additions & 2 deletions compiler/rustc_hir_typeck/src/place_op.rs
Original file line number Diff line number Diff line change
@@ -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
16 changes: 16 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
@@ -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> {
6 changes: 5 additions & 1 deletion compiler/rustc_middle/src/ty/visit.rs
Original file line number Diff line number Diff line change
@@ -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(())
}