@@ -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( ) ) ) ;
0 commit comments