@@ -688,7 +688,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
688688 let target_ty = self . monomorphize ( target_ty) ;
689689 let source_ty = self . monomorphize ( source_ty) ;
690690 let ( source_ty, target_ty) =
691- find_vtable_types_for_unsizing ( self . tcx . at ( span) , source_ty, target_ty) ;
691+ find_tails_for_unsizing ( self . tcx . at ( span) , source_ty, target_ty) ;
692692 // This could also be a different Unsize instruction, like
693693 // from a fixed sized array to a slice. But we are only
694694 // interested in things that produce a vtable.
@@ -1037,36 +1037,35 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) ->
10371037///
10381038/// Finally, there is also the case of custom unsizing coercions, e.g., for
10391039/// smart pointers such as `Rc` and `Arc`.
1040- fn find_vtable_types_for_unsizing < ' tcx > (
1040+ fn find_tails_for_unsizing < ' tcx > (
10411041 tcx : TyCtxtAt < ' tcx > ,
10421042 source_ty : Ty < ' tcx > ,
10431043 target_ty : Ty < ' tcx > ,
10441044) -> ( Ty < ' tcx > , Ty < ' tcx > ) {
1045- let ptr_vtable = |inner_source : Ty < ' tcx > , inner_target : Ty < ' tcx > | {
1046- let typing_env = ty:: TypingEnv :: fully_monomorphized ( ) ;
1047- if tcx. type_has_metadata ( inner_source, typing_env) {
1048- ( inner_source, inner_target)
1049- } else {
1050- tcx. struct_lockstep_tails_for_codegen ( inner_source, inner_target, typing_env)
1051- }
1052- } ;
1045+ let typing_env = ty:: TypingEnv :: fully_monomorphized ( ) ;
1046+ debug_assert ! ( !source_ty. has_param( ) , "{source_ty} should be fully monomorphic" ) ;
1047+ debug_assert ! ( !target_ty. has_param( ) , "{target_ty} should be fully monomorphic" ) ;
10531048
10541049 match ( source_ty. kind ( ) , target_ty. kind ( ) ) {
1055- ( & ty:: Ref ( _, a, _) , & ty:: Ref ( _, b, _) | & ty:: RawPtr ( b, _) )
1056- | ( & ty:: RawPtr ( a, _) , & ty:: RawPtr ( b, _) ) => ptr_vtable ( a, b) ,
1050+ (
1051+ & ty:: Ref ( _, source_pointee, _) ,
1052+ & ty:: Ref ( _, target_pointee, _) | & ty:: RawPtr ( target_pointee, _) ,
1053+ )
1054+ | ( & ty:: RawPtr ( source_pointee, _) , & ty:: RawPtr ( target_pointee, _) ) => {
1055+ tcx. struct_lockstep_tails_for_codegen ( source_pointee, target_pointee, typing_env)
1056+ }
1057+
1058+ // `Box<T>` could go through the ADT code below, b/c it'll unpeel to `Unique<T>`,
1059+ // and eventually bottom out in a raw ref, but we can micro-optimize it here.
10571060 ( _, _)
10581061 if let Some ( source_boxed) = source_ty. boxed_ty ( )
10591062 && let Some ( target_boxed) = target_ty. boxed_ty ( ) =>
10601063 {
1061- ptr_vtable ( source_boxed, target_boxed)
1064+ tcx . struct_lockstep_tails_for_codegen ( source_boxed, target_boxed, typing_env )
10621065 }
10631066
1064- // T as dyn* Trait
1065- ( _, & ty:: Dynamic ( _, _, ty:: DynStar ) ) => ptr_vtable ( source_ty, target_ty) ,
1066-
10671067 ( & ty:: Adt ( source_adt_def, source_args) , & ty:: Adt ( target_adt_def, target_args) ) => {
10681068 assert_eq ! ( source_adt_def, target_adt_def) ;
1069-
10701069 let CustomCoerceUnsized :: Struct ( coerce_index) =
10711070 match crate :: custom_coerce_unsize_info ( tcx, source_ty, target_ty) {
10721071 Ok ( ccu) => ccu,
@@ -1075,21 +1074,23 @@ fn find_vtable_types_for_unsizing<'tcx>(
10751074 return ( e, e) ;
10761075 }
10771076 } ;
1077+ let coerce_field = & source_adt_def. non_enum_variant ( ) . fields [ coerce_index] ;
1078+ // We're getting a possibly unnormalized type, so normalize it.
1079+ let source_field =
1080+ tcx. normalize_erasing_regions ( typing_env, coerce_field. ty ( * tcx, source_args) ) ;
1081+ let target_field =
1082+ tcx. normalize_erasing_regions ( typing_env, coerce_field. ty ( * tcx, target_args) ) ;
1083+ find_tails_for_unsizing ( tcx, source_field, target_field)
1084+ }
10781085
1079- let source_fields = & source_adt_def . non_enum_variant ( ) . fields ;
1080- let target_fields = & target_adt_def . non_enum_variant ( ) . fields ;
1081-
1082- assert ! (
1083- coerce_index . index ( ) < source_fields . len ( )
1084- && source_fields . len ( ) == target_fields . len ( )
1085- ) ;
1086+ // `T` as `dyn* Trait` unsizes *directly*.
1087+ //
1088+ // FIXME(dyn_star): This case is a bit awkward, b/c we're not really computing
1089+ // a tail here. We probably should handle this separately in the *caller* of
1090+ // this function, rather than returning something that is semantically different
1091+ // than what we return above.
1092+ ( _ , & ty :: Dynamic ( _ , _ , ty :: DynStar ) ) => ( source_ty , target_ty ) ,
10861093
1087- find_vtable_types_for_unsizing (
1088- tcx,
1089- source_fields[ coerce_index] . ty ( * tcx, source_args) ,
1090- target_fields[ coerce_index] . ty ( * tcx, target_args) ,
1091- )
1092- }
10931094 _ => bug ! (
10941095 "find_vtable_types_for_unsizing: invalid coercion {:?} -> {:?}" ,
10951096 source_ty,
@@ -1308,7 +1309,7 @@ fn visit_mentioned_item<'tcx>(
13081309 }
13091310 MentionedItem :: UnsizeCast { source_ty, target_ty } => {
13101311 let ( source_ty, target_ty) =
1311- find_vtable_types_for_unsizing ( tcx. at ( span) , source_ty, target_ty) ;
1312+ find_tails_for_unsizing ( tcx. at ( span) , source_ty, target_ty) ;
13121313 // This could also be a different Unsize instruction, like
13131314 // from a fixed sized array to a slice. But we are only
13141315 // interested in things that produce a vtable.
0 commit comments