@@ -18,6 +18,7 @@ use rustc_hir::def::DefKind;
18
18
use rustc_hir:: def_id:: DefId ;
19
19
use rustc_macros:: HashStable ;
20
20
use rustc_span:: Span ;
21
+ use rustc_target:: abi:: TargetDataLayout ;
21
22
use smallvec:: SmallVec ;
22
23
use std:: { cmp, fmt} ;
23
24
use syntax:: ast;
@@ -726,7 +727,7 @@ impl<'tcx> ty::TyS<'tcx> {
726
727
#[ inline]
727
728
pub fn needs_drop ( & ' tcx self , tcx : TyCtxt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> bool {
728
729
// Avoid querying in simple cases.
729
- match needs_drop_components ( self ) {
730
+ match needs_drop_components ( self , & tcx . data_layout ) {
730
731
Err ( AlwaysRequiresDrop ) => true ,
731
732
Ok ( components) => {
732
733
let query_ty = match * components {
@@ -736,7 +737,7 @@ impl<'tcx> ty::TyS<'tcx> {
736
737
[ component_ty] => component_ty,
737
738
_ => self ,
738
739
} ;
739
- // This doesn't depend on regions, so try to minimize distinct.
740
+ // This doesn't depend on regions, so try to minimize distinct
740
741
// query keys used.
741
742
let erased = tcx. normalize_erasing_regions ( param_env, query_ty) ;
742
743
tcx. needs_drop_raw ( param_env. and ( erased) )
@@ -992,7 +993,10 @@ impl<'tcx> ExplicitSelf<'tcx> {
992
993
/// Returns a list of types such that the given type needs drop if and only if
993
994
/// *any* of the returned types need drop. Returns `Err(AlwaysRequiresDrop)` if
994
995
/// 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 > {
996
1000
match ty. kind {
997
1001
ty:: Infer ( ty:: FreshIntTy ( _) )
998
1002
| ty:: Infer ( ty:: FreshFloatTy ( _) )
@@ -1017,18 +1021,25 @@ pub fn needs_drop_components(ty: Ty<'tcx>) -> Result<SmallVec<[Ty<'tcx>; 4]>, Al
1017
1021
// state transformation pass
1018
1022
ty:: Generator ( ..) | ty:: Dynamic ( ..) | ty:: Error => Err ( AlwaysRequiresDrop ) ,
1019
1023
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 ) {
1023
1027
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
+ } ,
1027
1038
}
1028
1039
}
1029
1040
// 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 ) ?) ;
1032
1043
Ok ( acc)
1033
1044
} ) ,
1034
1045
0 commit comments