Skip to content

Commit

Permalink
Use fewer delayed bugs.
Browse files Browse the repository at this point in the history
For some cases where it's clear that an error has already occurred,
e.g.:
- there's a comment stating exactly that, or
- things like HIR lowering, where we are lowering an error kind

The commit also tweaks some comments around delayed bug sites.
  • Loading branch information
nnethercote committed Feb 14, 2024
1 parent a84bb95 commit 82abcdf
Show file tree
Hide file tree
Showing 23 changed files with 88 additions and 90 deletions.
4 changes: 1 addition & 3 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
)
}
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
ExprKind::Err => {
hir::ExprKind::Err(self.dcx().span_delayed_bug(e.span, "lowered ExprKind::Err"))
}
ExprKind::Err => hir::ExprKind::Err(self.dcx().has_errors().unwrap()),
ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),

ExprKind::Paren(_) | ExprKind::ForLoop { .. } => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
match block {
Some(block) => self.lower_block_expr(block),
None => self.expr_err(span, self.dcx().span_delayed_bug(span, "no block")),
None => self.expr_err(span, self.dcx().has_errors().unwrap()),
}
}

Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1285,9 +1285,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
let kind = match &t.kind {
TyKind::Infer => hir::TyKind::Infer,
TyKind::Err => {
hir::TyKind::Err(self.dcx().span_delayed_bug(t.span, "TyKind::Err lowered"))
}
TyKind::Err => hir::TyKind::Err(self.dcx().has_errors().unwrap()),
// Lower the anonymous structs or unions in a nested lowering context.
//
// ```
Expand Down
20 changes: 8 additions & 12 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,14 @@ struct CfgChecker<'a, 'tcx> {
impl<'a, 'tcx> CfgChecker<'a, 'tcx> {
#[track_caller]
fn fail(&self, location: Location, msg: impl AsRef<str>) {
let span = self.body.source_info(location).span;
// We use `span_delayed_bug` as we might see broken MIR when other errors have already
// occurred.
self.tcx.dcx().span_delayed_bug(
span,
format!(
"broken MIR in {:?} ({}) at {:?}:\n{}",
self.body.source.instance,
self.when,
location,
msg.as_ref()
),
// We might see broken MIR when other errors have already occurred.
assert!(
self.tcx.dcx().has_errors().is_some(),
"broken MIR in {:?} ({}) at {:?}:\n{}",
self.body.source.instance,
self.when,
location,
msg.as_ref(),
);
}

Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_expand/src/mbe/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ pub(super) fn failed_to_match_macro<'cx>(
if try_success_result.is_ok() {
// Nonterminal parser recovery might turn failed matches into successful ones,
// but for that it must have emitted an error already
tracker
.cx
.dcx()
.span_delayed_bug(sp, "Macro matching returned a success on the second try");
assert!(
tracker.cx.dcx().has_errors().is_some(),
"Macro matching returned a success on the second try"
);
}

if let Some(result) = tracker.result {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -758,8 +758,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// since we should have emitten an error for them earlier, and they will
// not be well-formed!
if polarity == ty::ImplPolarity::Negative {
self.tcx().dcx().span_delayed_bug(
binding.span,
assert!(
self.tcx().dcx().has_errors().is_some(),
"negative trait bounds should not have bindings",
);
continue;
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1865,13 +1865,13 @@ fn check_variances_for_type_defn<'tcx>(
let hir_param = &hir_generics.params[index];

if ty_param.def_id != hir_param.def_id.into() {
// valid programs always have lifetimes before types in the generic parameter list
// Valid programs always have lifetimes before types in the generic parameter list.
// ty_generics are normalized to be in this required order, and variances are built
// from ty generics, not from hir generics. but we need hir generics to get
// a span out
// a span out.
//
// if they aren't in the same order, then the user has written invalid code, and already
// got an error about it (or I'm wrong about this)
// If they aren't in the same order, then the user has written invalid code, and already
// got an error about it (or I'm wrong about this).
tcx.dcx().span_delayed_bug(
hir_param.span,
"hir generics and ty generics in different order",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/coherence/unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub(super) fn check_item(

(_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative(_)) => {
// Reported in AST validation
tcx.dcx().span_delayed_bug(item.span, "unsafe negative impl");
assert!(tcx.dcx().has_errors().is_some(), "unsafe negative impl");
Ok(())
}
(_, _, Unsafety::Normal, hir::ImplPolarity::Negative(_))
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| ty::Never
| ty::Dynamic(_, _, ty::DynStar)
| ty::Error(_) => {
let reported = self
let guar = self
.dcx()
.span_delayed_bug(span, format!("`{t:?}` should be sized but is not?"));
return Err(reported);
return Err(guar);
}
})
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
if base_ty.is_none() {
// When encountering `return [0][0]` outside of a `fn` body we can encounter a base
// that isn't in the type table. We assume more relevant errors have already been
// emitted, so we delay an ICE if none have. (#64638)
self.tcx().dcx().span_delayed_bug(e.span, format!("bad base: `{base:?}`"));
// emitted. (#64638)
assert!(self.tcx().dcx().has_errors().is_some(), "bad base: `{base:?}`");
}
if let Some(base_ty) = base_ty
&& let ty::Ref(_, base_ty_inner, _) = *base_ty.kind()
Expand Down
14 changes: 6 additions & 8 deletions compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,14 +802,12 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}

// Errors in earlier passes can yield error variables without
// resolution errors here; delay ICE in favor of those errors.
self.tcx().dcx().span_delayed_bug(
self.var_infos[node_idx].origin.span(),
format!(
"collect_error_for_expanding_node() could not find \
error for var {node_idx:?} in universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \
upper_bounds={upper_bounds:#?}"
),
// resolution errors here; ICE if no errors have been emitted yet.
assert!(
self.tcx().dcx().has_errors().is_some(),
"collect_error_for_expanding_node() could not find error for var {node_idx:?} in \
universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \
upper_bounds={upper_bounds:#?}",
);
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_infer/src/infer/outlives/obligations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,9 @@ where
self.components_must_outlive(origin, subcomponents, region, category);
}
Component::UnresolvedInferenceVariable(v) => {
// ignore this, we presume it will yield an error
// later, since if a type variable is not resolved by
// this point it never will be
// Ignore this, we presume it will yield an error later,
// since if a type variable is not resolved by this point
// it never will be.
self.tcx.dcx().span_delayed_bug(
origin.span(),
format!("unresolved inference variable in outlives: {v:?}"),
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_infer/src/infer/outlives/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,13 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
self.bound_from_components(components, visited)
}
Component::UnresolvedInferenceVariable(v) => {
// ignore this, we presume it will yield an error
// later, since if a type variable is not resolved by
// this point it never will be
// Ignore this, we presume it will yield an error later, since
// if a type variable is not resolved by this point it never
// will be.
self.tcx
.dcx()
.delayed_bug(format!("unresolved inference variable in outlives: {v:?}"));
// add a bound that never holds
// Add a bound that never holds.
VerifyBound::AnyBound(vec![])
}
}
Expand Down
13 changes: 6 additions & 7 deletions compiler/rustc_lint/src/early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,14 +431,13 @@ pub fn check_ast_node_inner<'a, T: EarlyLintPass>(
// If not, that means that we somehow buffered a lint for a node id
// that was not lint-checked (perhaps it doesn't exist?). This is a bug.
for (id, lints) in cx.context.buffered.map {
for early_lint in lints {
sess.dcx().span_delayed_bug(
early_lint.span,
format!(
"failed to process buffered lint here (dummy = {})",
id == ast::DUMMY_NODE_ID
),
if !lints.is_empty() {
assert!(
sess.dcx().has_errors().is_some(),
"failed to process buffered lint here (dummy = {})",
id == ast::DUMMY_NODE_ID
);
break;
}
}
}
22 changes: 14 additions & 8 deletions compiler/rustc_mir_build/src/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
body_target_features: &'tcx [Symbol],
/// When inside the LHS of an assignment to a field, this is the type
/// of the LHS and the span of the assignment expression.
assignment_info: Option<(Ty<'tcx>, Span)>,
assignment_info: Option<Ty<'tcx>>,
in_union_destructure: bool,
param_env: ParamEnv<'tcx>,
inside_adt: bool,
Expand Down Expand Up @@ -473,10 +473,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
if let ty::Adt(adt_def, _) = lhs.ty.kind()
&& adt_def.is_union()
{
if let Some((assigned_ty, assignment_span)) = self.assignment_info {
if let Some(assigned_ty) = self.assignment_info {
if assigned_ty.needs_drop(self.tcx, self.param_env) {
// This would be unsafe, but should be outright impossible since we reject such unions.
self.tcx.dcx().span_delayed_bug(assignment_span, format!("union fields that need dropping should be impossible: {assigned_ty}"));
// This would be unsafe, but should be outright impossible since we
// reject such unions.
assert!(
self.tcx.dcx().has_errors().is_some(),
"union fields that need dropping should be impossible: \
{assigned_ty}"
);
}
} else {
self.requires_unsafe(expr.span, AccessToUnionField);
Expand All @@ -492,14 +497,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField);
}

// Second, check for accesses to union fields
// don't have any special handling for AssignOp since it causes a read *and* write to lhs
// Second, check for accesses to union fields. Don't have any
// special handling for AssignOp since it causes a read *and*
// write to lhs.
if matches!(expr.kind, ExprKind::Assign { .. }) {
self.assignment_info = Some((lhs.ty, expr.span));
self.assignment_info = Some(lhs.ty);
visit::walk_expr(self, lhs);
self.assignment_info = None;
visit::walk_expr(self, &self.thir()[rhs]);
return; // we have already visited everything by now
return; // We have already visited everything by now.
}
}
ExprKind::Borrow { borrow_kind, arg } => {
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,7 @@ impl<'tcx> ConstToPat<'tcx> {
// a hard error when we don't have a valtree or when we find something in
// the valtree that is not structural; then this can all be made a lot simpler.

let structural =
traits::search_for_structural_match_violation(self.span, self.tcx(), cv.ty());
let structural = traits::search_for_structural_match_violation(self.tcx(), cv.ty());
debug!(
"search_for_structural_match_violation cv.ty: {:?} returned: {:?}",
cv.ty(),
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_mir_transform/src/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,11 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
// old value is being dropped.
let assigned_ty = place.ty(&self.body.local_decls, self.tcx).ty;
if assigned_ty.needs_drop(self.tcx, self.param_env) {
// This would be unsafe, but should be outright impossible since we reject such unions.
self.tcx.dcx().span_delayed_bug(
self.source_info.span,
format!("union fields that need dropping should be impossible: {assigned_ty}")
// This would be unsafe, but should be outright impossible since we reject
// such unions.
assert!(
self.tcx.dcx().has_errors().is_some(),
"union fields that need dropping should be impossible: {assigned_ty}"
);
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
let body = &tcx.mir_const(def).borrow();

if body.return_ty().references_error() {
tcx.dcx().span_delayed_bug(body.span, "mir_const_qualif: MIR had errors");
assert!(tcx.dcx().has_errors().is_some(), "mir_const_qualif: MIR had errors");
return Default::default();
}

Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_query_system/src/query/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,16 +429,16 @@ where
let formatter = query.format_value();
if old_hash != new_hash {
// We have an inconsistency. This can happen if one of the two
// results is tainted by errors. In this case, delay a bug to
// ensure compilation is doomed.
qcx.dep_context().sess().dcx().delayed_bug(format!(
// results is tainted by errors.
assert!(
qcx.dep_context().sess().dcx().has_errors().is_some(),
"Computed query value for {:?}({:?}) is inconsistent with fed value,\n\
computed={:#?}\nfed={:#?}",
query.dep_kind(),
key,
formatter(&result),
formatter(&cached_result),
));
);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,10 @@ pub fn is_const_evaluatable<'tcx>(

match unexpanded_ct.kind() {
ty::ConstKind::Expr(_) => {
// FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete, but
// currently it is not possible to evaluate `ConstKind::Expr` so we are unable to tell if it
// is evaluatable or not. For now we just ICE until this is implemented.
// FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete,
// but currently it is not possible to evaluate `ConstKind::Expr` so we are unable
// to tell if it is evaluatable or not. For now we just ICE until this is
// implemented.
Err(NotConstEvaluatable::Error(tcx.dcx().span_delayed_bug(
span,
"evaluating `ConstKind::Expr` is not currently supported",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
}

// It could be that we don't report an error because we have seen an `ErrorReported` from another source.
// We should probably be able to fix most of these, but some are delayed bugs that get a proper error
// after this function.
// It could be that we don't report an error because we have seen an `ErrorReported` from
// another source. We should probably be able to fix most of these, but some are delayed
// bugs that get a proper error after this function.
reported.unwrap_or_else(|| self.dcx().delayed_bug("failed to report fulfillment errors"))
}

Expand Down Expand Up @@ -519,7 +519,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
trait_ref,
span,
) {
GetSafeTransmuteErrorAndReason::Silent => return self.dcx().span_delayed_bug(span, "silent safe transmute error"),
GetSafeTransmuteErrorAndReason::Silent => {
return self.dcx().span_delayed_bug(
span, "silent safe transmute error"
);
}
GetSafeTransmuteErrorAndReason::Error {
err_msg,
safe_transmute_explanation,
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_trait_selection/src/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ fn virtual_call_violations_for_method<'tcx>(

// NOTE: This check happens last, because it results in a lint, and not a
// hard error.
if tcx.predicates_of(method.def_id).predicates.iter().any(|&(pred, span)| {
if tcx.predicates_of(method.def_id).predicates.iter().any(|&(pred, _span)| {
// dyn Trait is okay:
//
// trait Trait {
Expand Down Expand Up @@ -594,7 +594,10 @@ fn virtual_call_violations_for_method<'tcx>(
// would already have reported an error at the definition of the
// auto trait.
if pred_trait_ref.args.len() != 1 {
tcx.dcx().span_delayed_bug(span, "auto traits cannot have generic parameters");
assert!(
tcx.dcx().has_errors().is_some(),
"auto traits cannot have generic parameters"
);
}
return false;
}
Expand Down
Loading

0 comments on commit 82abcdf

Please sign in to comment.