@@ -7,7 +7,7 @@ use crate::interpret::{
77 intern_const_alloc_recursive, ConstValue , ImmTy , Immediate , InternKind , MemPlaceMeta ,
88 MemoryKind , PlaceTy , Projectable , Scalar ,
99} ;
10- use rustc_middle:: ty:: layout:: { LayoutOf , TyAndLayout } ;
10+ use rustc_middle:: ty:: layout:: { LayoutCx , LayoutOf , TyAndLayout } ;
1111use rustc_middle:: ty:: { self , ScalarInt , Ty , TyCtxt } ;
1212use rustc_span:: source_map:: DUMMY_SP ;
1313use rustc_target:: abi:: VariantIdx ;
@@ -239,6 +239,21 @@ pub fn valtree_to_const_value<'tcx>(
239239 // Fast path to avoid some allocations.
240240 return ConstValue :: ZeroSized ;
241241 }
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+ }
242257
243258 let mut ecx = mk_eval_cx ( tcx, DUMMY_SP , param_env, CanAccessStatics :: No ) ;
244259
0 commit comments