@@ -216,6 +216,7 @@ struct VnState<'body, 'tcx> {
216
216
tcx : TyCtxt < ' tcx > ,
217
217
ecx : InterpCx < ' tcx , DummyMachine > ,
218
218
local_decls : & ' body LocalDecls < ' tcx > ,
219
+ is_coroutine : bool ,
219
220
/// Value stored in each local.
220
221
locals : IndexVec < Local , Option < VnIndex > > ,
221
222
/// Locals that are assigned that value.
@@ -253,6 +254,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
253
254
tcx,
254
255
ecx : InterpCx :: new ( tcx, DUMMY_SP , typing_env, DummyMachine ) ,
255
256
local_decls,
257
+ is_coroutine : body. coroutine . is_some ( ) ,
256
258
locals : IndexVec :: from_elem ( None , local_decls) ,
257
259
rev_locals : IndexVec :: with_capacity ( num_values) ,
258
260
values : FxIndexSet :: with_capacity_and_hasher ( num_values, Default :: default ( ) ) ,
@@ -380,7 +382,12 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
380
382
fn eval_to_const ( & mut self , value : VnIndex ) -> Option < OpTy < ' tcx > > {
381
383
use Value :: * ;
382
384
let ty = self . ty ( value) ;
383
- let ty = self . ecx . layout_of ( ty) . ok ( ) ?;
385
+ // Avoid computing layouts inside a coroutine, as that can cause cycles.
386
+ let ty = if !self . is_coroutine || ty. is_scalar ( ) {
387
+ self . ecx . layout_of ( ty) . ok ( ) ?
388
+ } else {
389
+ return None ;
390
+ } ;
384
391
let op = match * self . get ( value) {
385
392
_ if ty. is_zst ( ) => ImmTy :: uninit ( ty) . into ( ) ,
386
393
0 commit comments