@@ -688,7 +688,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
688
688
let target_ty = self . monomorphize ( target_ty) ;
689
689
let source_ty = self . monomorphize ( source_ty) ;
690
690
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) ;
692
692
// This could also be a different Unsize instruction, like
693
693
// from a fixed sized array to a slice. But we are only
694
694
// interested in things that produce a vtable.
@@ -1037,36 +1037,35 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) ->
1037
1037
///
1038
1038
/// Finally, there is also the case of custom unsizing coercions, e.g., for
1039
1039
/// smart pointers such as `Rc` and `Arc`.
1040
- fn find_vtable_types_for_unsizing < ' tcx > (
1040
+ fn find_tails_for_unsizing < ' tcx > (
1041
1041
tcx : TyCtxtAt < ' tcx > ,
1042
1042
source_ty : Ty < ' tcx > ,
1043
1043
target_ty : Ty < ' tcx > ,
1044
1044
) -> ( 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" ) ;
1053
1048
1054
1049
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.
1057
1060
( _, _)
1058
1061
if let Some ( source_boxed) = source_ty. boxed_ty ( )
1059
1062
&& let Some ( target_boxed) = target_ty. boxed_ty ( ) =>
1060
1063
{
1061
- ptr_vtable ( source_boxed, target_boxed)
1064
+ tcx . struct_lockstep_tails_for_codegen ( source_boxed, target_boxed, typing_env )
1062
1065
}
1063
1066
1064
- // T as dyn* Trait
1065
- ( _, & ty:: Dynamic ( _, _, ty:: DynStar ) ) => ptr_vtable ( source_ty, target_ty) ,
1066
-
1067
1067
( & ty:: Adt ( source_adt_def, source_args) , & ty:: Adt ( target_adt_def, target_args) ) => {
1068
1068
assert_eq ! ( source_adt_def, target_adt_def) ;
1069
-
1070
1069
let CustomCoerceUnsized :: Struct ( coerce_index) =
1071
1070
match crate :: custom_coerce_unsize_info ( tcx, source_ty, target_ty) {
1072
1071
Ok ( ccu) => ccu,
@@ -1075,21 +1074,23 @@ fn find_vtable_types_for_unsizing<'tcx>(
1075
1074
return ( e, e) ;
1076
1075
}
1077
1076
} ;
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
+ }
1078
1085
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 ) ,
1086
1093
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
- }
1093
1094
_ => bug ! (
1094
1095
"find_vtable_types_for_unsizing: invalid coercion {:?} -> {:?}" ,
1095
1096
source_ty,
@@ -1308,7 +1309,7 @@ fn visit_mentioned_item<'tcx>(
1308
1309
}
1309
1310
MentionedItem :: UnsizeCast { source_ty, target_ty } => {
1310
1311
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) ;
1312
1313
// This could also be a different Unsize instruction, like
1313
1314
// from a fixed sized array to a slice. But we are only
1314
1315
// interested in things that produce a vtable.
0 commit comments