Skip to content

Delayed bug audit #121285

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
merged 7 commits into from
Feb 27, 2024
8 changes: 2 additions & 6 deletions compiler/rustc_ast_lowering/src/delegation.rs
Original file line number Diff line number Diff line change
@@ -103,12 +103,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: Span,
) -> Result<DefId, ErrorGuaranteed> {
let sig_id = if self.is_in_trait_impl { item_id } else { path_id };
let sig_id = self
.resolver
.get_partial_res(sig_id)
.map(|r| r.expect_full_res().opt_def_id())
.unwrap_or(None);

let sig_id =
self.resolver.get_partial_res(sig_id).and_then(|r| r.expect_full_res().opt_def_id());
sig_id.ok_or_else(|| {
self.tcx
.dcx()
18 changes: 11 additions & 7 deletions compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Error reporting machinery for lifetime errors.
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{Applicability, DiagnosticBuilder, MultiSpan};
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::Res::Def;
use rustc_hir::def_id::DefId;
@@ -73,7 +73,7 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
///
/// Usually we expect this to either be empty or contain a small number of items, so we can avoid
/// allocation most of the time.
pub(crate) struct RegionErrors<'tcx>(Vec<RegionErrorKind<'tcx>>, TyCtxt<'tcx>);
pub(crate) struct RegionErrors<'tcx>(Vec<(RegionErrorKind<'tcx>, ErrorGuaranteed)>, TyCtxt<'tcx>);

impl<'tcx> RegionErrors<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
@@ -82,15 +82,18 @@ impl<'tcx> RegionErrors<'tcx> {
#[track_caller]
pub fn push(&mut self, val: impl Into<RegionErrorKind<'tcx>>) {
let val = val.into();
self.1.sess.dcx().delayed_bug(format!("{val:?}"));
self.0.push(val);
let guar = self.1.sess.dcx().delayed_bug(format!("{val:?}"));
self.0.push((val, guar));
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn into_iter(self) -> impl Iterator<Item = RegionErrorKind<'tcx>> {
pub fn into_iter(self) -> impl Iterator<Item = (RegionErrorKind<'tcx>, ErrorGuaranteed)> {
self.0.into_iter()
}
pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
self.0.get(0).map(|x| x.1)
}
}

impl std::fmt::Debug for RegionErrors<'_> {
@@ -304,10 +307,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let mut last_unexpected_hidden_region: Option<(Span, Ty<'_>, ty::OpaqueTypeKey<'tcx>)> =
None;

for nll_error in nll_errors.into_iter() {
for (nll_error, _) in nll_errors.into_iter() {
match nll_error {
RegionErrorKind::TypeTestError { type_test } => {
// Try to convert the lower-bound region into something named we can print for the user.
// Try to convert the lower-bound region into something named we can print for
// the user.
let lower_bound_region = self.to_error_region(type_test.lower_bound);

let type_test_span = type_test.span;
7 changes: 2 additions & 5 deletions compiler/rustc_borrowck/src/nll.rs
Original file line number Diff line number Diff line change
@@ -184,12 +184,9 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
let (closure_region_requirements, nll_errors) =
regioncx.solve(infcx, body, polonius_output.clone());

if !nll_errors.is_empty() {
if let Some(guar) = nll_errors.has_errors() {
// Suppress unhelpful extra errors in `infer_opaque_types`.
infcx.set_tainted_by_errors(infcx.dcx().span_delayed_bug(
body.span,
"`compute_regions` tainted `infcx` with errors but did not emit any errors",
));
infcx.set_tainted_by_errors(guar);
}

let remapped_opaque_tys = regioncx.infer_opaque_types(infcx, opaque_type_values);
11 changes: 4 additions & 7 deletions compiler/rustc_borrowck/src/type_check/free_region_relations.rs
Original file line number Diff line number Diff line change
@@ -311,17 +311,14 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
// Add implied bounds from impl header.
if matches!(tcx.def_kind(defining_ty_def_id), DefKind::AssocFn | DefKind::AssocConst) {
for &(ty, _) in tcx.assumed_wf_types(tcx.local_parent(defining_ty_def_id)) {
let Ok(TypeOpOutput { output: norm_ty, constraints: c, .. }) = self
let result: Result<_, ErrorGuaranteed> = self
.param_env
.and(type_op::normalize::Normalize::new(ty))
.fully_perform(self.infcx, span)
else {
// Note: this path is currently not reached in any test, so
// any example that triggers this would be worth minimizing
// and converting into a test.
tcx.dcx().span_delayed_bug(span, format!("failed to normalize {ty:?}"));
.fully_perform(self.infcx, span);
let Ok(TypeOpOutput { output: norm_ty, constraints: c, .. }) = result else {
continue;
};

constraints.extend(c);

// We currently add implied bounds from the normalized ty only.
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
@@ -760,7 +760,7 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
prev_discr = Some(
if let ty::VariantDiscr::Explicit(const_def_id) = variant.discr {
def.eval_explicit_discr(tcx, const_def_id)
def.eval_explicit_discr(tcx, const_def_id).ok()
} else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
Some(discr)
} else {
55 changes: 26 additions & 29 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
@@ -428,6 +428,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
generic_param_scope: LocalDefId,
errors: &[RegionResolutionError<'tcx>],
) -> ErrorGuaranteed {
assert!(!errors.is_empty());

if let Some(guaranteed) = self.infcx.tainted_by_errors() {
return guaranteed;
}
@@ -440,10 +442,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {

debug!("report_region_errors: {} errors after preprocessing", errors.len());

let mut guar = None;
for error in errors {
debug!("report_region_errors: error = {:?}", error);

if !self.try_report_nice_region_error(&error) {
guar = Some(if let Some(guar) = self.try_report_nice_region_error(&error) {
guar
} else {
match error.clone() {
// These errors could indicate all manner of different
// problems with many different solutions. Rather
@@ -454,21 +459,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// general bit of code that displays the error information
RegionResolutionError::ConcreteFailure(origin, sub, sup) => {
if sub.is_placeholder() || sup.is_placeholder() {
self.report_placeholder_failure(origin, sub, sup).emit();
self.report_placeholder_failure(origin, sub, sup).emit()
} else {
self.report_concrete_failure(origin, sub, sup).emit();
self.report_concrete_failure(origin, sub, sup).emit()
}
}

RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => {
self.report_generic_bound_failure(
RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => self
.report_generic_bound_failure(
generic_param_scope,
origin.span(),
Some(origin),
param_ty,
sub,
);
}
),

RegionResolutionError::SubSupConflict(
_,
@@ -480,13 +484,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
_,
) => {
if sub_r.is_placeholder() {
self.report_placeholder_failure(sub_origin, sub_r, sup_r).emit();
self.report_placeholder_failure(sub_origin, sub_r, sup_r).emit()
} else if sup_r.is_placeholder() {
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit()
} else {
self.report_sub_sup_conflict(
var_origin, sub_origin, sub_r, sup_origin, sup_r,
);
)
}
}

@@ -506,7 +510,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// value.
let sub_r = self.tcx.lifetimes.re_erased;

self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit()
}

RegionResolutionError::CannotNormalize(clause, origin) => {
@@ -515,15 +519,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
self.tcx
.dcx()
.struct_span_err(origin.span(), format!("cannot normalize `{clause}`"))
.emit();
.emit()
}
}
}
})
}

self.tcx
.dcx()
.span_delayed_bug(self.tcx.def_span(generic_param_scope), "expected region errors")
guar.unwrap()
}

// This method goes through all the errors and try to group certain types
@@ -2314,9 +2316,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
origin: Option<SubregionOrigin<'tcx>>,
bound_kind: GenericKind<'tcx>,
sub: Region<'tcx>,
) {
) -> ErrorGuaranteed {
self.construct_generic_bound_failure(generic_param_scope, span, origin, bound_kind, sub)
.emit();
.emit()
}

pub fn construct_generic_bound_failure(
@@ -2575,7 +2577,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
sub_region: Region<'tcx>,
sup_origin: SubregionOrigin<'tcx>,
sup_region: Region<'tcx>,
) {
) -> ErrorGuaranteed {
let mut err = self.report_inference_failure(var_origin);

note_and_explain_region(
@@ -2614,12 +2616,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
);

err.note_expected_found(&"", sup_expected, &"", sup_found);
if sub_region.is_error() | sup_region.is_error() {
err.delay_as_bug();
return if sub_region.is_error() | sup_region.is_error() {
err.delay_as_bug()
} else {
err.emit();
}
return;
err.emit()
};
}

self.note_region_origin(&mut err, &sup_origin);
@@ -2634,11 +2635,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
);

self.note_region_origin(&mut err, &sub_origin);
if sub_region.is_error() | sup_region.is_error() {
err.delay_as_bug();
} else {
err.emit();
}
if sub_region.is_error() | sup_region.is_error() { err.delay_as_bug() } else { err.emit() }
}

/// Determine whether an error associated with the given span and definition
Original file line number Diff line number Diff line change
@@ -21,8 +21,11 @@ pub use static_impl_trait::{suggest_new_region_bound, HirTraitObjectVisitor, Tra
pub use util::find_param_with_region;

impl<'cx, 'tcx> TypeErrCtxt<'cx, 'tcx> {
pub fn try_report_nice_region_error(&'cx self, error: &RegionResolutionError<'tcx>) -> bool {
NiceRegionError::new(self, error.clone()).try_report().is_some()
pub fn try_report_nice_region_error(
&'cx self,
error: &RegionResolutionError<'tcx>,
) -> Option<ErrorGuaranteed> {
NiceRegionError::new(self, error.clone()).try_report()
}
}

37 changes: 24 additions & 13 deletions compiler/rustc_middle/src/ty/adt.rs
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::intern::Interned;
use rustc_data_structures::stable_hasher::HashingControls;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::DefId;
@@ -475,7 +476,11 @@ impl<'tcx> AdtDef<'tcx> {
}

#[inline]
pub fn eval_explicit_discr(self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<Discr<'tcx>> {
pub fn eval_explicit_discr(
self,
tcx: TyCtxt<'tcx>,
expr_did: DefId,
) -> Result<Discr<'tcx>, ErrorGuaranteed> {
assert!(self.is_enum());
let param_env = tcx.param_env(expr_did);
let repr_type = self.repr().discr_type();
@@ -484,22 +489,24 @@ impl<'tcx> AdtDef<'tcx> {
let ty = repr_type.to_ty(tcx);
if let Some(b) = val.try_to_bits_for_ty(tcx, param_env, ty) {
trace!("discriminants: {} ({:?})", b, repr_type);
Some(Discr { val: b, ty })
Ok(Discr { val: b, ty })
} else {
info!("invalid enum discriminant: {:#?}", val);
tcx.dcx().emit_err(crate::error::ConstEvalNonIntError {
let guar = tcx.dcx().emit_err(crate::error::ConstEvalNonIntError {
span: tcx.def_span(expr_did),
});
None
Err(guar)
}
}
Err(err) => {
let msg = match err {
ErrorHandled::Reported(..) => "enum discriminant evaluation failed",
ErrorHandled::TooGeneric(..) => "enum discriminant depends on generics",
let guar = match err {
ErrorHandled::Reported(info, _) => info.into(),
ErrorHandled::TooGeneric(..) => tcx.dcx().span_delayed_bug(
tcx.def_span(expr_did),
"enum discriminant depends on generics",
),
};
tcx.dcx().span_delayed_bug(tcx.def_span(expr_did), msg);
None
Err(guar)
}
}
}
@@ -516,7 +523,7 @@ impl<'tcx> AdtDef<'tcx> {
self.variants().iter_enumerated().map(move |(i, v)| {
let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
if let VariantDiscr::Explicit(expr_did) = v.discr {
if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) {
if let Ok(new_discr) = self.eval_explicit_discr(tcx, expr_did) {
discr = new_discr;
}
}
@@ -544,9 +551,13 @@ impl<'tcx> AdtDef<'tcx> {
) -> Discr<'tcx> {
assert!(self.is_enum());
let (val, offset) = self.discriminant_def_for_variant(variant_index);
let explicit_value = val
.and_then(|expr_did| self.eval_explicit_discr(tcx, expr_did))
.unwrap_or_else(|| self.repr().discr_type().initial_discriminant(tcx));
let explicit_value = if let Some(expr_did) = val
&& let Ok(val) = self.eval_explicit_discr(tcx, expr_did)
{
val
} else {
self.repr().discr_type().initial_discriminant(tcx)
};
explicit_value.checked_add(tcx, offset as u128).0
}

29 changes: 13 additions & 16 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
@@ -2688,23 +2688,20 @@ impl<'a> Parser<'a> {
branch_span: Span,
attrs: AttrWrapper,
) {
if attrs.is_empty() {
return;
if !attrs.is_empty()
&& let [x0 @ xn] | [x0, .., xn] = &*attrs.take_for_recovery(self.sess)
{
let attributes = x0.span.to(xn.span);
let last = xn.span;
let ctx = if is_ctx_else { "else" } else { "if" };
self.dcx().emit_err(errors::OuterAttributeNotAllowedOnIfElse {
last,
branch_span,
ctx_span,
ctx: ctx.to_string(),
attributes,
});
}

let attrs: &[ast::Attribute] = &attrs.take_for_recovery(self.sess);
let (attributes, last) = match attrs {
[] => return,
[x0 @ xn] | [x0, .., xn] => (x0.span.to(xn.span), xn.span),
};
let ctx = if is_ctx_else { "else" } else { "if" };
self.dcx().emit_err(errors::OuterAttributeNotAllowedOnIfElse {
last,
branch_span,
ctx_span,
ctx: ctx.to_string(),
attributes,
});
}

fn error_on_extra_if(&mut self, cond: &P<Expr>) -> PResult<'a, ()> {
3 changes: 1 addition & 2 deletions compiler/rustc_parse/src/parser/stmt.rs
Original file line number Diff line number Diff line change
@@ -230,8 +230,7 @@ impl<'a> Parser<'a> {
/// Also error if the previous token was a doc comment.
fn error_outer_attrs(&self, attrs: AttrWrapper) {
if !attrs.is_empty()
&& let attrs = attrs.take_for_recovery(self.sess)
&& let attrs @ [.., last] = &*attrs
&& let attrs @ [.., last] = &*attrs.take_for_recovery(self.sess)
{
if last.is_doc_comment() {
self.dcx().emit_err(errors::DocCommentDoesNotDocumentAnything {
8 changes: 6 additions & 2 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -554,8 +554,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
///
/// This takes the error provided, combines it with the span and any additional spans inside the
/// error and emits it.
pub(crate) fn report_error(&mut self, span: Span, resolution_error: ResolutionError<'a>) {
self.into_struct_error(span, resolution_error).emit();
pub(crate) fn report_error(
&mut self,
span: Span,
resolution_error: ResolutionError<'a>,
) -> ErrorGuaranteed {
self.into_struct_error(span, resolution_error).emit()
}

pub(crate) fn into_struct_error(
5 changes: 2 additions & 3 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use rustc_ast::{self as ast, NodeId};
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::{DefKind, Namespace, NonMacroAttrKind, PartialRes, PerNS};
use rustc_middle::bug;
use rustc_middle::ty;
@@ -1066,7 +1067,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
original_rib_ident_def: Ident,
all_ribs: &[Rib<'a>],
) -> Res {
const CG_BUG_STR: &str = "min_const_generics resolve check didn't stop compilation";
debug!("validate_res_from_ribs({:?})", res);
let ribs = &all_ribs[rib_index + 1..];

@@ -1209,8 +1209,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}
};
self.report_error(span, error);
self.dcx().span_delayed_bug(span, CG_BUG_STR);
let _: ErrorGuaranteed = self.report_error(span, error);
}

return Res::Err;