Skip to content

Commit 1e9bb85

Browse files
committed
Check for impossible preds before evaluating definitions
1 parent ef54806 commit 1e9bb85

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

+44
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,50 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
335335
tcx: TyCtxt<'tcx>,
336336
key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
337337
) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
338+
// Avoid evaluating instances with impossible bounds required to hold as
339+
// this can result in executing code that should never be executed.
340+
//
341+
// We handle this in interpreter internals instead of at callsites (such as
342+
// type system normalization or match exhaustiveness handling) as basically
343+
// *every* place that we invoke CTFE should not be doing so on definitions
344+
// with impossible bounds. Handling it here ensures that we can be certain
345+
// that we haven't missed anywhere.
346+
let instance_def = key.value.instance.def_id();
347+
if tcx.def_kind(instance_def) == DefKind::AnonConst
348+
&& let ty::AnonConstKind::GCEConst = tcx.anon_const_kind(instance_def)
349+
{ // ... do nothing for GCE anon consts as it would cycle
350+
} else if tcx.def_kind(instance_def) == DefKind::AnonConst
351+
&& let ty::AnonConstKind::RepeatExprCount = tcx.anon_const_kind(instance_def)
352+
{
353+
// Instead of erroring when encountering a repeat expr hack const with impossible
354+
// preds we just FCW, as anon consts are unnameable and this code *might* wind up
355+
// supported one day if the anon const is a path expr.
356+
if tcx.instantiate_and_check_impossible_predicates((
357+
instance_def,
358+
tcx.erase_regions(key.value.instance.args),
359+
)) {
360+
if let Some(local_def) = instance_def.as_local() {
361+
tcx.node_span_lint(
362+
rustc_session::lint::builtin::CONST_EVALUATABLE_UNCHECKED,
363+
tcx.local_def_id_to_hir_id(local_def),
364+
tcx.def_span(instance_def),
365+
|lint| {
366+
lint.primary_message(
367+
"cannot use constants which depend on trivially-false where clauses",
368+
);
369+
},
370+
)
371+
} else {
372+
// If the repeat expr count is from some upstream crate then we don't care to
373+
// lint on it as it should have been linted on when compiling the upstream crate.
374+
}
375+
};
376+
} else if tcx
377+
.instantiate_and_check_impossible_predicates((instance_def, key.value.instance.args))
378+
{
379+
return Err(ErrorHandled::TooGeneric(tcx.def_span(instance_def)));
380+
}
381+
338382
// This shouldn't be used for statics, since statics are conceptually places,
339383
// not values -- so what we do here could break pointer identity.
340384
assert!(key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id()));

0 commit comments

Comments
 (0)