Skip to content
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

Delayed bug audit #121285

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
Expand Up @@ -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()
Expand Down
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;
Expand Down Expand Up @@ -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 {
Expand All @@ -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<'_> {
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_borrowck/src/nll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
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
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
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
Expand Up @@ -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;
}
Expand All @@ -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
Expand All @@ -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(
_,
Expand All @@ -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,
);
)
}
}

Expand All @@ -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) => {
Expand All @@ -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
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}

Expand Down
37 changes: 24 additions & 13 deletions compiler/rustc_middle/src/ty/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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)
}
}
}
Expand All @@ -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;
}
}
Expand Down Expand Up @@ -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
}

Expand Down
29 changes: 13 additions & 16 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, ()> {
Expand Down
Loading
Loading