@@ -426,7 +426,7 @@ impl<'tcx> CPlace<'tcx> {
426426 }
427427
428428 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 ) ;
430430
431431 self . write_cvalue_maybe_transmute ( fx, from, "write_cvalue" ) ;
432432 }
@@ -788,18 +788,25 @@ pub(crate) fn assert_assignable<'tcx>(
788788 fx : & FunctionCx < ' _ , ' _ , ' tcx > ,
789789 from_ty : Ty < ' tcx > ,
790790 to_ty : Ty < ' tcx > ,
791+ limit : usize ,
791792) {
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+ }
792799 match ( from_ty. kind ( ) , to_ty. kind ( ) ) {
793800 ( ty:: Ref ( _, a, _) , ty:: Ref ( _, b, _) )
794801 | (
795802 ty:: RawPtr ( TypeAndMut { ty : a, mutbl : _ } ) ,
796803 ty:: RawPtr ( TypeAndMut { ty : b, mutbl : _ } ) ,
797804 ) => {
798- assert_assignable ( fx, * a, * b) ;
805+ assert_assignable ( fx, * a, * b, limit - 1 ) ;
799806 }
800807 ( ty:: Ref ( _, a, _) , ty:: RawPtr ( TypeAndMut { ty : b, mutbl : _ } ) )
801808 | ( ty:: RawPtr ( TypeAndMut { ty : a, mutbl : _ } ) , ty:: Ref ( _, b, _) ) => {
802- assert_assignable ( fx, * a, * b) ;
809+ assert_assignable ( fx, * a, * b, limit - 1 ) ;
803810 }
804811 ( ty:: FnPtr ( _) , ty:: FnPtr ( _) ) => {
805812 let from_sig = fx. tcx . normalize_erasing_late_bound_regions (
@@ -829,25 +836,55 @@ pub(crate) fn assert_assignable<'tcx>(
829836 }
830837 // dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
831838 }
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+ }
832850 ( & ty:: Adt ( adt_def_a, substs_a) , & ty:: Adt ( adt_def_b, substs_b) )
833851 if adt_def_a. did ( ) == adt_def_b. did ( ) =>
834852 {
835853 let mut types_a = substs_a. types ( ) ;
836854 let mut types_b = substs_b. types ( ) ;
837855 loop {
838856 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 ) ,
840858 ( None , None ) => return ,
841859 ( Some ( _) , None ) | ( None , Some ( _) ) => panic ! ( "{:#?}/{:#?}" , from_ty, to_ty) ,
842860 }
843861 }
844862 }
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+ }
846880 _ => {
847881 assert_eq ! (
848- from_ty, to_ty,
882+ from_ty,
883+ to_ty,
849884 "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,
851888 ) ;
852889 }
853890 }
0 commit comments