@@ -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