@@ -14,9 +14,9 @@ use rustc_middle::mir::visit::{
1414 MutVisitor , MutatingUseContext , NonMutatingUseContext , PlaceContext , Visitor ,
1515} ;
1616use rustc_middle:: mir:: {
17- AggregateKind , AssertKind , BasicBlock , BinOp , Body , ClearCrossCrate , Constant , Local ,
18- LocalDecl , LocalKind , Location , Operand , Place , Rvalue , SourceInfo , SourceScope ,
19- SourceScopeData , Statement , StatementKind , Terminator , TerminatorKind , UnOp , RETURN_PLACE ,
17+ AssertKind , BasicBlock , BinOp , Body , ClearCrossCrate , Constant , Local , LocalDecl , LocalKind ,
18+ Location , Operand , Place , Rvalue , SourceInfo , SourceScope , SourceScopeData , Statement ,
19+ StatementKind , Terminator , TerminatorKind , UnOp , RETURN_PLACE ,
2020} ;
2121use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutError , TyAndLayout } ;
2222use rustc_middle:: ty:: subst:: { InternalSubsts , Subst } ;
@@ -28,9 +28,9 @@ use rustc_trait_selection::traits;
2828
2929use crate :: const_eval:: ConstEvalErr ;
3030use crate :: interpret:: {
31- self , compile_time_machine, truncate, AllocId , Allocation , Frame , ImmTy , Immediate , InterpCx ,
32- LocalState , LocalValue , MemPlace , Memory , MemoryKind , OpTy , Operand as InterpOperand , PlaceTy ,
33- Pointer , ScalarMaybeUninit , StackPopCleanup ,
31+ self , compile_time_machine, truncate, AllocId , Allocation , ConstValue , Frame , ImmTy , Immediate ,
32+ InterpCx , LocalState , LocalValue , MemPlace , Memory , MemoryKind , OpTy , Operand as InterpOperand ,
33+ PlaceTy , Pointer , ScalarMaybeUninit , StackPopCleanup ,
3434} ;
3535use crate :: transform:: { MirPass , MirSource } ;
3636
@@ -824,44 +824,57 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
824824 ) ) ;
825825 }
826826 Immediate :: ScalarPair (
827- ScalarMaybeUninit :: Scalar ( one ) ,
828- ScalarMaybeUninit :: Scalar ( two ) ,
827+ ScalarMaybeUninit :: Scalar ( _ ) ,
828+ ScalarMaybeUninit :: Scalar ( _ ) ,
829829 ) => {
830- // Found a value represented as a pair. For now only do cont-prop if type of
831- // Rvalue is also a pair with two scalars. The more general case is more
832- // complicated to implement so we'll do it later.
833- // FIXME: implement the general case stated above ^.
834- let ty = & value. layout . ty . kind ;
830+ // Found a value represented as a pair. For now only do const-prop if the type
831+ // of `rvalue` is also a tuple with two scalars.
832+ // FIXME: enable the general case stated above ^.
833+ let ty = & value. layout . ty ;
835834 // Only do it for tuples
836- if let ty:: Tuple ( substs) = ty {
835+ if let ty:: Tuple ( substs) = ty. kind {
837836 // Only do it if tuple is also a pair with two scalars
838837 if substs. len ( ) == 2 {
839- let opt_ty1_ty2 = self . use_ecx ( |this| {
838+ let alloc = self . use_ecx ( |this| {
840839 let ty1 = substs[ 0 ] . expect_ty ( ) ;
841840 let ty2 = substs[ 1 ] . expect_ty ( ) ;
842841 let ty_is_scalar = |ty| {
843842 this. ecx . layout_of ( ty) . ok ( ) . map ( |layout| layout. abi . is_scalar ( ) )
844843 == Some ( true )
845844 } ;
846845 if ty_is_scalar ( ty1) && ty_is_scalar ( ty2) {
847- Ok ( Some ( ( ty1, ty2) ) )
846+ let alloc = this
847+ . ecx
848+ . intern_with_temp_alloc ( value. layout , |ecx, dest| {
849+ ecx. write_immediate_to_mplace ( * imm, dest)
850+ } )
851+ . unwrap ( ) ;
852+ Ok ( Some ( alloc) )
848853 } else {
849854 Ok ( None )
850855 }
851856 } ) ;
852857
853- if let Some ( Some ( ( ty1, ty2) ) ) = opt_ty1_ty2 {
854- * rval = Rvalue :: Aggregate (
855- Box :: new ( AggregateKind :: Tuple ) ,
856- vec ! [
857- self . operand_from_scalar( one, ty1, source_info. span) ,
858- self . operand_from_scalar( two, ty2, source_info. span) ,
859- ] ,
860- ) ;
858+ if let Some ( Some ( alloc) ) = alloc {
859+ // Assign entire constant in a single statement.
860+ // We can't use aggregates, as we run after the aggregate-lowering `MirPhase`.
861+ * rval = Rvalue :: Use ( Operand :: Constant ( Box :: new ( Constant {
862+ span : source_info. span ,
863+ user_ty : None ,
864+ literal : self . ecx . tcx . mk_const ( ty:: Const {
865+ ty,
866+ val : ty:: ConstKind :: Value ( ConstValue :: ByRef {
867+ alloc,
868+ offset : Size :: ZERO ,
869+ } ) ,
870+ } ) ,
871+ } ) ) ) ;
861872 }
862873 }
863874 }
864875 }
876+ // Scalars or scalar pairs that contain undef values are assumed to not have
877+ // successfully evaluated and are thus not propagated.
865878 _ => { }
866879 }
867880 }
0 commit comments