@@ -18,6 +18,7 @@ use rustc_hir::def::DefKind;
1818use rustc_hir:: def_id:: DefId ;
1919use rustc_macros:: HashStable ;
2020use rustc_span:: Span ;
21+ use rustc_target:: abi:: TargetDataLayout ;
2122use smallvec:: SmallVec ;
2223use std:: { cmp, fmt} ;
2324use syntax:: ast;
@@ -726,7 +727,7 @@ impl<'tcx> ty::TyS<'tcx> {
726727 #[ inline]
727728 pub fn needs_drop ( & ' tcx self , tcx : TyCtxt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> bool {
728729 // Avoid querying in simple cases.
729- match needs_drop_components ( self ) {
730+ match needs_drop_components ( self , & tcx . data_layout ) {
730731 Err ( AlwaysRequiresDrop ) => true ,
731732 Ok ( components) => {
732733 let query_ty = match * components {
@@ -736,7 +737,7 @@ impl<'tcx> ty::TyS<'tcx> {
736737 [ component_ty] => component_ty,
737738 _ => self ,
738739 } ;
739- // This doesn't depend on regions, so try to minimize distinct.
740+ // This doesn't depend on regions, so try to minimize distinct
740741 // query keys used.
741742 let erased = tcx. normalize_erasing_regions ( param_env, query_ty) ;
742743 tcx. needs_drop_raw ( param_env. and ( erased) )
@@ -992,7 +993,10 @@ impl<'tcx> ExplicitSelf<'tcx> {
992993/// Returns a list of types such that the given type needs drop if and only if
993994/// *any* of the returned types need drop. Returns `Err(AlwaysRequiresDrop)` if
994995/// this type always needs drop.
995- pub fn needs_drop_components ( ty : Ty < ' tcx > ) -> Result < SmallVec < [ Ty < ' tcx > ; 4 ] > , AlwaysRequiresDrop > {
996+ pub fn needs_drop_components (
997+ ty : Ty < ' tcx > ,
998+ target_layout : & TargetDataLayout ,
999+ ) -> Result < SmallVec < [ Ty < ' tcx > ; 2 ] > , AlwaysRequiresDrop > {
9961000 match ty. kind {
9971001 ty:: Infer ( ty:: FreshIntTy ( _) )
9981002 | ty:: Infer ( ty:: FreshFloatTy ( _) )
@@ -1017,18 +1021,25 @@ pub fn needs_drop_components(ty: Ty<'tcx>) -> Result<SmallVec<[Ty<'tcx>; 4]>, Al
10171021 // state transformation pass
10181022 ty:: Generator ( ..) | ty:: Dynamic ( ..) | ty:: Error => Err ( AlwaysRequiresDrop ) ,
10191023
1020- ty:: Slice ( ty) => needs_drop_components ( ty) ,
1021- ty:: Array ( elem_ty, .. ) => {
1022- match needs_drop_components ( elem_ty) {
1024+ ty:: Slice ( ty) => needs_drop_components ( ty, target_layout ) ,
1025+ ty:: Array ( elem_ty, size ) => {
1026+ match needs_drop_components ( elem_ty, target_layout ) {
10231027 Ok ( v) if v. is_empty ( ) => Ok ( v) ,
1024- // Arrays of size zero don't need drop, even if their element
1025- // type does.
1026- _ => Ok ( smallvec ! [ ty] ) ,
1028+ res => match size. val . try_to_bits ( target_layout. pointer_size ) {
1029+ // Arrays of size zero don't need drop, even if their element
1030+ // type does.
1031+ Some ( 0 ) => Ok ( SmallVec :: new ( ) ) ,
1032+ Some ( _) => res,
1033+ // We don't know which of the cases above we are in, so
1034+ // return the whole type and let the caller decide what to
1035+ // do.
1036+ None => Ok ( smallvec ! [ ty] ) ,
1037+ } ,
10271038 }
10281039 }
10291040 // If any field needs drop, then the whole tuple does.
1030- ty:: Tuple ( ..) => ty. tuple_fields ( ) . try_fold ( SmallVec :: new ( ) , |mut acc, elem| {
1031- acc. extend ( needs_drop_components ( elem) ?) ;
1041+ ty:: Tuple ( ..) => ty. tuple_fields ( ) . try_fold ( SmallVec :: new ( ) , move |mut acc, elem| {
1042+ acc. extend ( needs_drop_components ( elem, target_layout ) ?) ;
10321043 Ok ( acc)
10331044 } ) ,
10341045
0 commit comments