@@ -14,9 +14,9 @@ use rustc_middle::mir::visit::{
14
14
MutVisitor , MutatingUseContext , NonMutatingUseContext , PlaceContext , Visitor ,
15
15
} ;
16
16
use 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 ,
20
20
} ;
21
21
use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutError , TyAndLayout } ;
22
22
use rustc_middle:: ty:: subst:: { InternalSubsts , Subst } ;
@@ -28,9 +28,9 @@ use rustc_trait_selection::traits;
28
28
29
29
use crate :: const_eval:: ConstEvalErr ;
30
30
use 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 ,
34
34
} ;
35
35
use crate :: transform:: { MirPass , MirSource } ;
36
36
@@ -824,44 +824,57 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
824
824
) ) ;
825
825
}
826
826
Immediate :: ScalarPair (
827
- ScalarMaybeUninit :: Scalar ( one ) ,
828
- ScalarMaybeUninit :: Scalar ( two ) ,
827
+ ScalarMaybeUninit :: Scalar ( _ ) ,
828
+ ScalarMaybeUninit :: Scalar ( _ ) ,
829
829
) => {
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 ;
835
834
// Only do it for tuples
836
- if let ty:: Tuple ( substs) = ty {
835
+ if let ty:: Tuple ( substs) = ty. kind {
837
836
// Only do it if tuple is also a pair with two scalars
838
837
if substs. len ( ) == 2 {
839
- let opt_ty1_ty2 = self . use_ecx ( |this| {
838
+ let alloc = self . use_ecx ( |this| {
840
839
let ty1 = substs[ 0 ] . expect_ty ( ) ;
841
840
let ty2 = substs[ 1 ] . expect_ty ( ) ;
842
841
let ty_is_scalar = |ty| {
843
842
this. ecx . layout_of ( ty) . ok ( ) . map ( |layout| layout. abi . is_scalar ( ) )
844
843
== Some ( true )
845
844
} ;
846
845
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) )
848
853
} else {
849
854
Ok ( None )
850
855
}
851
856
} ) ;
852
857
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
+ } ) ) ) ;
861
872
}
862
873
}
863
874
}
864
875
}
876
+ // Scalars or scalar pairs that contain undef values are assumed to not have
877
+ // successfully evaluated and are thus not propagated.
865
878
_ => { }
866
879
}
867
880
}
0 commit comments