@@ -335,6 +335,50 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
335
335
tcx : TyCtxt < ' tcx > ,
336
336
key : ty:: PseudoCanonicalInput < ' tcx , GlobalId < ' tcx > > ,
337
337
) -> :: 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
+
338
382
// This shouldn't be used for statics, since statics are conceptually places,
339
383
// not values -- so what we do here could break pointer identity.
340
384
assert ! ( key. value. promoted. is_some( ) || !tcx. is_static( key. value. instance. def_id( ) ) ) ;
0 commit comments