@@ -7,7 +7,7 @@ use crate::interpret::{
7
7
intern_const_alloc_recursive, ConstValue , ImmTy , Immediate , InternKind , MemPlaceMeta ,
8
8
MemoryKind , PlaceTy , Projectable , Scalar ,
9
9
} ;
10
- use rustc_middle:: ty:: layout:: { LayoutOf , TyAndLayout } ;
10
+ use rustc_middle:: ty:: layout:: { LayoutCx , LayoutOf , TyAndLayout } ;
11
11
use rustc_middle:: ty:: { self , ScalarInt , Ty , TyCtxt } ;
12
12
use rustc_span:: source_map:: DUMMY_SP ;
13
13
use rustc_target:: abi:: VariantIdx ;
@@ -239,6 +239,21 @@ pub fn valtree_to_const_value<'tcx>(
239
239
// Fast path to avoid some allocations.
240
240
return ConstValue :: ZeroSized ;
241
241
}
242
+ if layout. abi . is_scalar ( )
243
+ && ( matches ! ( ty. kind( ) , ty:: Tuple ( _) )
244
+ || matches ! ( ty. kind( ) , ty:: Adt ( def, _) if def. is_struct( ) ) )
245
+ {
246
+ // A Scalar tuple/struct; we can avoid creating an allocation.
247
+ let branches = valtree. unwrap_branch ( ) ;
248
+ // Find the non-ZST field. (There can be aligned ZST!)
249
+ for ( i, & inner_valtree) in branches. iter ( ) . enumerate ( ) {
250
+ let field = layout. field ( & LayoutCx { tcx, param_env } , i) ;
251
+ if !field. is_zst ( ) {
252
+ return valtree_to_const_value ( tcx, param_env. and ( field. ty ) , inner_valtree) ;
253
+ }
254
+ }
255
+ bug ! ( "could not find non-ZST field during in {layout:#?}" ) ;
256
+ }
242
257
243
258
let mut ecx = mk_eval_cx ( tcx, DUMMY_SP , param_env, CanAccessStatics :: No ) ;
244
259
0 commit comments