mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Auto merge of #121285 - nnethercote:delayed_bug-audit, r=lcnr
Delayed bug audit I went through all the calls to `delayed_bug` and `span_delayed_bug` and found a few places where they could be avoided. r? `@compiler-errors`
This commit is contained in:
commit
9afdb8d1d5
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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, ()> {
|
||||
|
@ -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 {
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user