@@ -426,7 +426,7 @@ impl<'tcx> CPlace<'tcx> {
426
426
}
427
427
428
428
pub ( crate ) fn write_cvalue ( self , fx : & mut FunctionCx < ' _ , ' _ , ' tcx > , from : CValue < ' tcx > ) {
429
- assert_assignable ( fx, from. layout ( ) . ty , self . layout ( ) . ty ) ;
429
+ assert_assignable ( fx, from. layout ( ) . ty , self . layout ( ) . ty , 16 ) ;
430
430
431
431
self . write_cvalue_maybe_transmute ( fx, from, "write_cvalue" ) ;
432
432
}
@@ -788,18 +788,25 @@ pub(crate) fn assert_assignable<'tcx>(
788
788
fx : & FunctionCx < ' _ , ' _ , ' tcx > ,
789
789
from_ty : Ty < ' tcx > ,
790
790
to_ty : Ty < ' tcx > ,
791
+ limit : usize ,
791
792
) {
793
+ if limit == 0 {
794
+ // assert_assignable exists solely to catch bugs in cg_clif. it isn't necessary for
795
+ // soundness. don't attempt to check deep types to avoid exponential behavior in certain
796
+ // cases.
797
+ return ;
798
+ }
792
799
match ( from_ty. kind ( ) , to_ty. kind ( ) ) {
793
800
( ty:: Ref ( _, a, _) , ty:: Ref ( _, b, _) )
794
801
| (
795
802
ty:: RawPtr ( TypeAndMut { ty : a, mutbl : _ } ) ,
796
803
ty:: RawPtr ( TypeAndMut { ty : b, mutbl : _ } ) ,
797
804
) => {
798
- assert_assignable ( fx, * a, * b) ;
805
+ assert_assignable ( fx, * a, * b, limit - 1 ) ;
799
806
}
800
807
( ty:: Ref ( _, a, _) , ty:: RawPtr ( TypeAndMut { ty : b, mutbl : _ } ) )
801
808
| ( ty:: RawPtr ( TypeAndMut { ty : a, mutbl : _ } ) , ty:: Ref ( _, b, _) ) => {
802
- assert_assignable ( fx, * a, * b) ;
809
+ assert_assignable ( fx, * a, * b, limit - 1 ) ;
803
810
}
804
811
( ty:: FnPtr ( _) , ty:: FnPtr ( _) ) => {
805
812
let from_sig = fx. tcx . normalize_erasing_late_bound_regions (
@@ -829,25 +836,55 @@ pub(crate) fn assert_assignable<'tcx>(
829
836
}
830
837
// dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
831
838
}
839
+ ( & ty:: Tuple ( types_a) , & ty:: Tuple ( types_b) ) => {
840
+ let mut types_a = types_a. iter ( ) ;
841
+ let mut types_b = types_b. iter ( ) ;
842
+ loop {
843
+ match ( types_a. next ( ) , types_b. next ( ) ) {
844
+ ( Some ( a) , Some ( b) ) => assert_assignable ( fx, a, b, limit - 1 ) ,
845
+ ( None , None ) => return ,
846
+ ( Some ( _) , None ) | ( None , Some ( _) ) => panic ! ( "{:#?}/{:#?}" , from_ty, to_ty) ,
847
+ }
848
+ }
849
+ }
832
850
( & ty:: Adt ( adt_def_a, substs_a) , & ty:: Adt ( adt_def_b, substs_b) )
833
851
if adt_def_a. did ( ) == adt_def_b. did ( ) =>
834
852
{
835
853
let mut types_a = substs_a. types ( ) ;
836
854
let mut types_b = substs_b. types ( ) ;
837
855
loop {
838
856
match ( types_a. next ( ) , types_b. next ( ) ) {
839
- ( Some ( a) , Some ( b) ) => assert_assignable ( fx, a, b) ,
857
+ ( Some ( a) , Some ( b) ) => assert_assignable ( fx, a, b, limit - 1 ) ,
840
858
( None , None ) => return ,
841
859
( Some ( _) , None ) | ( None , Some ( _) ) => panic ! ( "{:#?}/{:#?}" , from_ty, to_ty) ,
842
860
}
843
861
}
844
862
}
845
- ( ty:: Array ( a, _) , ty:: Array ( b, _) ) => assert_assignable ( fx, * a, * b) ,
863
+ ( ty:: Array ( a, _) , ty:: Array ( b, _) ) => assert_assignable ( fx, * a, * b, limit - 1 ) ,
864
+ ( & ty:: Closure ( def_id_a, substs_a) , & ty:: Closure ( def_id_b, substs_b) )
865
+ if def_id_a == def_id_b =>
866
+ {
867
+ let mut types_a = substs_a. types ( ) ;
868
+ let mut types_b = substs_b. types ( ) ;
869
+ loop {
870
+ match ( types_a. next ( ) , types_b. next ( ) ) {
871
+ ( Some ( a) , Some ( b) ) => assert_assignable ( fx, a, b, limit - 1 ) ,
872
+ ( None , None ) => return ,
873
+ ( Some ( _) , None ) | ( None , Some ( _) ) => panic ! ( "{:#?}/{:#?}" , from_ty, to_ty) ,
874
+ }
875
+ }
876
+ }
877
+ ( ty:: Param ( _) , _) | ( _, ty:: Param ( _) ) if fx. tcx . sess . opts . unstable_opts . polymorphize => {
878
+ // No way to check if it is correct or not with polymorphization enabled
879
+ }
846
880
_ => {
847
881
assert_eq ! (
848
- from_ty, to_ty,
882
+ from_ty,
883
+ to_ty,
849
884
"Can't write value with incompatible type {:?} to place with type {:?}\n \n {:#?}" ,
850
- from_ty, to_ty, fx,
885
+ from_ty. kind( ) ,
886
+ to_ty. kind( ) ,
887
+ fx,
851
888
) ;
852
889
}
853
890
}
0 commit comments