@@ -23,11 +23,16 @@ fn needs_drop_raw<'tcx>(
2323 // needs drop.
2424 let adt_has_dtor =
2525 |adt_def : ty:: AdtDef < ' tcx > | adt_def. destructor ( tcx) . map ( |_| DtorType :: Significant ) ;
26- let res =
27- drop_tys_helper ( tcx, query. value , query. typing_env , adt_has_dtor, false , false , false )
28- . filter ( filter_array_elements ( tcx, query. typing_env ) )
29- . next ( )
30- . is_some ( ) ;
26+ let res = drop_tys_helper (
27+ tcx,
28+ query. value ,
29+ query. typing_env ,
30+ adt_has_dtor,
31+ DropTysOptions :: default ( ) ,
32+ )
33+ . filter ( filter_array_elements ( tcx, query. typing_env ) )
34+ . next ( )
35+ . is_some ( ) ;
3136
3237 debug ! ( "needs_drop_raw({:?}) = {:?}" , query, res) ;
3338 res
@@ -42,11 +47,16 @@ fn needs_async_drop_raw<'tcx>(
4247 // it needs async drop.
4348 let adt_has_async_dtor =
4449 |adt_def : ty:: AdtDef < ' tcx > | adt_def. async_destructor ( tcx) . map ( |_| DtorType :: Significant ) ;
45- let res =
46- drop_tys_helper ( tcx, query. value , query. typing_env , adt_has_async_dtor, false , false , true )
47- . filter ( filter_array_elements_async ( tcx, query. typing_env ) )
48- . next ( )
49- . is_some ( ) ;
50+ let res = drop_tys_helper (
51+ tcx,
52+ query. value ,
53+ query. typing_env ,
54+ adt_has_async_dtor,
55+ DropTysOptions :: default ( ) . recurse_into_box_for_async_drop ( ) ,
56+ )
57+ . filter ( filter_array_elements_async ( tcx, query. typing_env ) )
58+ . next ( )
59+ . is_some ( ) ;
5060
5161 debug ! ( "needs_async_drop_raw({:?}) = {:?}" , query, res) ;
5262 res
@@ -90,9 +100,7 @@ fn has_significant_drop_raw<'tcx>(
90100 query. value ,
91101 query. typing_env ,
92102 adt_consider_insignificant_dtor ( tcx) ,
93- true ,
94- false ,
95- false ,
103+ DropTysOptions :: default ( ) . only_significant ( ) ,
96104 )
97105 . filter ( filter_array_elements ( tcx, query. typing_env ) )
98106 . next ( )
@@ -323,6 +331,30 @@ enum DtorType {
323331 Significant ,
324332}
325333
334+ #[ derive( Copy , Clone , Default ) ]
335+ struct DropTysOptions {
336+ only_significant : bool ,
337+ exhaustive : bool ,
338+ async_drop_recurses_into_box : bool ,
339+ }
340+
341+ impl DropTysOptions {
342+ fn only_significant ( mut self ) -> Self {
343+ self . only_significant = true ;
344+ self
345+ }
346+
347+ fn exhaustive ( mut self ) -> Self {
348+ self . exhaustive = true ;
349+ self
350+ }
351+
352+ fn recurse_into_box_for_async_drop ( mut self ) -> Self {
353+ self . async_drop_recurses_into_box = true ;
354+ self
355+ }
356+ }
357+
326358// This is a helper function for `adt_drop_tys` and `adt_significant_drop_tys`.
327359// Depending on the implantation of `adt_has_dtor`, it is used to check if the
328360// ADT has a destructor or if the ADT only has a significant destructor. For
@@ -332,9 +364,7 @@ fn drop_tys_helper<'tcx>(
332364 ty : Ty < ' tcx > ,
333365 typing_env : ty:: TypingEnv < ' tcx > ,
334366 adt_has_dtor : impl Fn ( ty:: AdtDef < ' tcx > ) -> Option < DtorType > ,
335- only_significant : bool ,
336- exhaustive : bool ,
337- async_drop_recurses_into_box : bool ,
367+ options : DropTysOptions ,
338368) -> impl Iterator < Item = NeedsDropResult < Ty < ' tcx > > > {
339369 fn with_query_cache < ' tcx > (
340370 tcx : TyCtxt < ' tcx > ,
@@ -357,14 +387,32 @@ fn drop_tys_helper<'tcx>(
357387 if adt_def. is_manually_drop ( ) {
358388 debug ! ( "drop_tys_helper: `{:?}` is manually drop" , adt_def) ;
359389 Ok ( Vec :: new ( ) )
360- } else if async_drop_recurses_into_box && adt_def. is_box ( ) {
361- let boxed_ty = args. type_at ( 0 ) ;
362- let allocator_ty = args. get ( 1 ) . map ( |arg| arg. expect_ty ( ) ) ;
363- let boxed_ty = match boxed_ty. kind ( ) {
364- ty:: Dynamic ( ..) | ty:: Error ( _) => None ,
365- _ => Some ( boxed_ty) ,
390+ } else if options. async_drop_recurses_into_box && adt_def. is_box ( ) {
391+ let box_components = match args. as_slice ( ) {
392+ [ boxed_ty, allocator_ty] => {
393+ let boxed_ty = boxed_ty. expect_ty ( ) ;
394+ let allocator_ty = allocator_ty. expect_ty ( ) ;
395+ match boxed_ty. kind ( ) {
396+ // FIXME(async_drop): boxed dyn pointees are deliberately skipped here
397+ // because async drop glue does not yet dispatch through dyn metadata.
398+ // Once that is supported, this should include the boxed pointee too.
399+ ty:: Dynamic ( ..) | ty:: Error ( _) => vec ! [ allocator_ty] ,
400+ _ => vec ! [ boxed_ty, allocator_ty] ,
401+ }
402+ }
403+ [ boxed_ty] => {
404+ let boxed_ty = boxed_ty. expect_ty ( ) ;
405+ match boxed_ty. kind ( ) {
406+ ty:: Dynamic ( ..) | ty:: Error ( _) => Vec :: new ( ) ,
407+ _ => vec ! [ boxed_ty] ,
408+ }
409+ }
410+ _ => {
411+ debug ! ( ?args, "drop_tys_helper: `Box` has unexpected generic args" ) ;
412+ Vec :: new ( )
413+ }
366414 } ;
367- Ok ( [ boxed_ty , allocator_ty ] . into_iter ( ) . flatten ( ) . collect ( ) )
415+ Ok ( box_components )
368416 } else if let Some ( dtor_info) = adt_has_dtor ( adt_def) {
369417 match dtor_info {
370418 DtorType :: Significant => {
@@ -392,7 +440,7 @@ fn drop_tys_helper<'tcx>(
392440 ) ;
393441 r
394442 } ) ;
395- if only_significant {
443+ if options . only_significant {
396444 // We can't recurse through the query system here because we might induce a cycle
397445 Ok ( field_tys. collect ( ) )
398446 } else {
@@ -406,7 +454,7 @@ fn drop_tys_helper<'tcx>(
406454 . map ( |v| v. into_iter ( ) )
407455 } ;
408456
409- NeedsDropTypes :: new ( tcx, typing_env, ty, exhaustive, adt_components)
457+ NeedsDropTypes :: new ( tcx, typing_env, ty, options . exhaustive , adt_components)
410458}
411459
412460fn adt_consider_insignificant_dtor < ' tcx > (
@@ -445,9 +493,7 @@ fn adt_drop_tys<'tcx>(
445493 tcx. type_of ( def_id) . instantiate_identity ( ) . skip_norm_wip ( ) ,
446494 ty:: TypingEnv :: non_body_analysis ( tcx, def_id) ,
447495 adt_has_dtor,
448- false ,
449- false ,
450- false ,
496+ DropTysOptions :: default ( ) ,
451497 )
452498 . collect :: < Result < Vec < _ > , _ > > ( )
453499 . map ( |components| tcx. mk_type_list ( & components) )
@@ -466,9 +512,7 @@ fn adt_async_drop_tys<'tcx>(
466512 tcx. type_of ( def_id) . instantiate_identity ( ) . skip_norm_wip ( ) ,
467513 ty:: TypingEnv :: non_body_analysis ( tcx, def_id) ,
468514 adt_has_dtor,
469- false ,
470- false ,
471- true ,
515+ DropTysOptions :: default ( ) . recurse_into_box_for_async_drop ( ) ,
472516 )
473517 . collect :: < Result < Vec < _ > , _ > > ( )
474518 . map ( |components| tcx. mk_type_list ( & components) )
@@ -486,9 +530,7 @@ fn adt_significant_drop_tys(
486530 tcx. type_of ( def_id) . instantiate_identity ( ) . skip_norm_wip ( ) , // identical to `tcx.make_adt(def, identity_args)`
487531 ty:: TypingEnv :: non_body_analysis ( tcx, def_id) ,
488532 adt_consider_insignificant_dtor ( tcx) ,
489- true ,
490- false ,
491- false ,
533+ DropTysOptions :: default ( ) . only_significant ( ) ,
492534 )
493535 . collect :: < Result < Vec < _ > , _ > > ( )
494536 . map ( |components| tcx. mk_type_list ( & components) )
@@ -505,9 +547,7 @@ fn list_significant_drop_tys<'tcx>(
505547 key. value ,
506548 key. typing_env ,
507549 adt_consider_insignificant_dtor ( tcx) ,
508- true ,
509- true ,
510- false ,
550+ DropTysOptions :: default ( ) . only_significant ( ) . exhaustive ( ) ,
511551 )
512552 . filter_map ( |res| res. ok ( ) )
513553 . collect :: < Vec < _ > > ( ) ,
0 commit comments