Skip to content

Commit c63659c

Browse files
committed
Remove the ImpossibleClauses err variant
1 parent a074dda commit c63659c

File tree

6 files changed

+41
-72
lines changed

6 files changed

+41
-72
lines changed

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,44 @@ 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+
let instance_def = key.value.instance.def_id();
341+
if tcx.def_kind(instance_def) == DefKind::AnonConst
342+
&& let ty::AnonConstKind::GCEConst = tcx.anon_const_kind(instance_def)
343+
{ // ... do nothing for GCE anon consts as it would cycle
344+
} else if tcx.def_kind(instance_def) == DefKind::AnonConst
345+
&& let ty::AnonConstKind::RepeatExprCount = tcx.anon_const_kind(instance_def)
346+
{
347+
// Instead of erroring when encountering a repeat expr hack const with impossible
348+
// preds we just FCW, as anon consts are unnameable and this code *might* wind up
349+
// supported one day if the anon const is a path expr.
350+
if tcx.instantiate_and_check_impossible_predicates((
351+
instance_def,
352+
tcx.erase_regions(key.value.instance.args),
353+
)) {
354+
if let Some(local_def) = instance_def.as_local() {
355+
tcx.node_span_lint(
356+
rustc_session::lint::builtin::CONST_EVALUATABLE_UNCHECKED,
357+
tcx.local_def_id_to_hir_id(local_def),
358+
tcx.def_span(instance_def),
359+
|lint| {
360+
lint.primary_message(
361+
"cannot use constants which depend on trivially-false where clauses",
362+
);
363+
},
364+
)
365+
} else {
366+
// If the repeat expr count is from some upstream crate then we don't care to
367+
// lint on it as it should have been linted on when compiling the upstream crate.
368+
}
369+
};
370+
} else if tcx
371+
.instantiate_and_check_impossible_predicates((instance_def, key.value.instance.args))
372+
{
373+
return Err(ErrorHandled::TooGeneric(tcx.def_span(instance_def)));
374+
}
375+
338376
// This shouldn't be used for statics, since statics are conceptually places,
339377
// not values -- so what we do here could break pointer identity.
340378
assert!(key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id()));

compiler/rustc_trait_selection/src/solve/delegate.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
8585
Ok(ct) => Some(ct),
8686
Err(EvaluateConstErr::EvaluationFailure(e)) => Some(ty::Const::new_error(self.tcx, e)),
8787
Err(
88-
EvaluateConstErr::ImpossibleClauses
89-
| EvaluateConstErr::InvalidConstParamTy(_)
90-
| EvaluateConstErr::HasGenericsOrInfers,
88+
EvaluateConstErr::InvalidConstParamTy(_) | EvaluateConstErr::HasGenericsOrInfers,
9189
) => None,
9290
}
9391
}

compiler/rustc_trait_selection/src/traits/const_evaluatable.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,6 @@ pub fn is_const_evaluatable<'tcx>(
7676
"Missing value for constant, but no error reported?",
7777
)))
7878
}
79-
Err(EvaluateConstErr::ImpossibleClauses) => {
80-
unreachable!("under gce constants shouldnt be wf checked before evaluating")
81-
}
8279
Err(
8380
EvaluateConstErr::EvaluationFailure(e)
8481
| EvaluateConstErr::InvalidConstParamTy(e),
@@ -154,12 +151,6 @@ pub fn is_const_evaluatable<'tcx>(
154151

155152
Err(err)
156153
}
157-
Err(EvaluateConstErr::ImpossibleClauses) => {
158-
let e = tcx
159-
.dcx()
160-
.delayed_bug("constants with impossible preds shouldnt error on stable");
161-
return Err(NotConstEvaluatable::Error(e));
162-
}
163154
Err(
164155
EvaluateConstErr::EvaluationFailure(e) | EvaluateConstErr::InvalidConstParamTy(e),
165156
) => Err(NotConstEvaluatable::Error(e)),

compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -687,8 +687,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
687687
}
688688
e @ Err(
689689
EvaluateConstErr::EvaluationFailure(_)
690-
| EvaluateConstErr::InvalidConstParamTy(_)
691-
| EvaluateConstErr::ImpossibleClauses,
690+
| EvaluateConstErr::InvalidConstParamTy(_),
692691
) => e,
693692
}
694693
} else {
@@ -716,10 +715,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
716715
}
717716
}
718717
}
719-
(Err(EvaluateConstErr::ImpossibleClauses), _)
720-
| (_, Err(EvaluateConstErr::ImpossibleClauses)) => unreachable!(
721-
"under gce constants shouldnt be wf checked before evaluating"
722-
),
723718
(Err(EvaluateConstErr::InvalidConstParamTy(e)), _)
724719
| (_, Err(EvaluateConstErr::InvalidConstParamTy(e))) => {
725720
ProcessResult::Error(FulfillmentErrorCode::Select(

compiler/rustc_trait_selection/src/traits/mod.rs

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ use rustc_middle::ty::{
3838
self, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFolder, TypeSuperFoldable,
3939
TypeSuperVisitable, TypingMode, Upcast,
4040
};
41-
use rustc_session::lint;
4241
use rustc_span::def_id::DefId;
4342
use rustc_span::{DUMMY_SP, Span};
4443
use tracing::{debug, instrument};
@@ -493,10 +492,6 @@ pub enum EvaluateConstErr {
493492
/// CTFE failed to evaluate the constant in some unrecoverable way (e.g. encountered a `panic!`).
494493
/// This is also used when the constant was already tainted by error.
495494
EvaluationFailure(ErrorGuaranteed),
496-
/// The constant requires impossible clauses to hold in order for it to be evaluated. This does not
497-
/// necessarily imply that type checking should error as there may be similar impossible clauses in
498-
/// the type checking environment that can be used to prove this constant wf.
499-
ImpossibleClauses,
500495
}
501496

502497
// FIXME(BoxyUwU): Private this once we `generic_const_exprs` isn't doing its own normalization routine
@@ -518,7 +513,7 @@ pub fn evaluate_const<'tcx>(
518513
Err(EvaluateConstErr::EvaluationFailure(e) | EvaluateConstErr::InvalidConstParamTy(e)) => {
519514
ty::Const::new_error(infcx.tcx, e)
520515
}
521-
Err(EvaluateConstErr::ImpossibleClauses | EvaluateConstErr::HasGenericsOrInfers) => ct,
516+
Err(EvaluateConstErr::HasGenericsOrInfers) => ct,
522517
}
523518
}
524519

@@ -635,30 +630,6 @@ pub fn try_evaluate_const<'tcx>(
635630
let args = GenericArgs::identity_for_item(tcx, uv.def);
636631
let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def);
637632

638-
// Instead of erroring when encountering a constant with impossible preds we just FCW, as
639-
// it would be a breaking change.
640-
if tcx
641-
.instantiate_and_check_impossible_predicates((uv.def, tcx.erase_regions(args)))
642-
{
643-
if let Some(local_def) = uv.def.as_local() {
644-
tcx.node_span_lint(
645-
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
646-
tcx.local_def_id_to_hir_id(local_def),
647-
tcx.def_span(uv.def),
648-
|lint| {
649-
lint.primary_message(
650-
"cannot use constants which depend on trivially-false where clauses",
651-
);
652-
},
653-
)
654-
} else {
655-
// If the anon const is not a local def then it's probably a GCE const from some
656-
// upstream crate. We don't need to lint on that. It also shouldn't be possible
657-
// for an upstream crate to put a repeat expr count anon const into a signature
658-
// and have it *only* evaluated in a downstream crate.
659-
}
660-
};
661-
662633
(args, typing_env)
663634
} else {
664635
// We are only dealing with "truly" generic/uninferred constants here:
@@ -671,24 +642,6 @@ pub fn try_evaluate_const<'tcx>(
671642
return Err(EvaluateConstErr::HasGenericsOrInfers);
672643
}
673644

674-
// If we are dealing with a fully monomorphic constant then we should ensure that
675-
// it is well formed as otherwise CTFE will ICE. For the same reasons as with
676-
// deferring evaluation of generic/uninferred constants, we do not have to worry
677-
// about `generic_const_exprs`
678-
//
679-
// This check is done in an empty environment which is a little weird, however, mir
680-
// bodies with impossible predicates (in an empty environment) are sometimes built as
681-
// only an `unreachable` terminator which makes evaluating them incorrect even if the
682-
// impossible pred is satsifiable in this environment.
683-
if tcx.instantiate_and_check_impossible_predicates((
684-
uv.def,
685-
tcx.erase_regions(uv.args),
686-
)) {
687-
// We can't delay a bug here as that could ICE the compiler if we are in an environment
688-
// where the impossible pred actually holds due to it also existing in this env.
689-
return Err(EvaluateConstErr::ImpossibleClauses);
690-
}
691-
692645
let typing_env = infcx
693646
.typing_env(tcx.erase_regions(param_env))
694647
.with_post_analysis_normalized(tcx);

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -932,12 +932,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
932932
Err(_) => Ok(EvaluatedToErr),
933933
}
934934
}
935-
(Err(EvaluateConstErr::ImpossibleClauses), _)
936-
| (_, Err(EvaluateConstErr::ImpossibleClauses)) => {
937-
unreachable!(
938-
"under gce constants shouldnt be wf checked before evaluating"
939-
)
940-
}
941935
(Err(EvaluateConstErr::InvalidConstParamTy(..)), _)
942936
| (_, Err(EvaluateConstErr::InvalidConstParamTy(..))) => Ok(EvaluatedToErr),
943937
(Err(EvaluateConstErr::EvaluationFailure(..)), _)

0 commit comments

Comments
 (0)