@@ -23,10 +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 = drop_tys_helper ( tcx, query. value , query. typing_env , adt_has_dtor, false , false )
27- . filter ( filter_array_elements ( tcx, query. typing_env ) )
28- . next ( )
29- . 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 ( ) ;
3036
3137 debug ! ( "needs_drop_raw({:?}) = {:?}" , query, res) ;
3238 res
@@ -41,10 +47,16 @@ fn needs_async_drop_raw<'tcx>(
4147 // it needs async drop.
4248 let adt_has_async_dtor =
4349 |adt_def : ty:: AdtDef < ' tcx > | adt_def. async_destructor ( tcx) . map ( |_| DtorType :: Significant ) ;
44- let res = drop_tys_helper ( tcx, query. value , query. typing_env , adt_has_async_dtor, false , false )
45- . filter ( filter_array_elements_async ( tcx, query. typing_env ) )
46- . next ( )
47- . 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 ( ) ;
4860
4961 debug ! ( "needs_async_drop_raw({:?}) = {:?}" , query, res) ;
5062 res
@@ -88,8 +100,7 @@ fn has_significant_drop_raw<'tcx>(
88100 query. value ,
89101 query. typing_env ,
90102 adt_consider_insignificant_dtor ( tcx) ,
91- true ,
92- false ,
103+ DropTysOptions :: default ( ) . only_significant ( ) ,
93104 )
94105 . filter ( filter_array_elements ( tcx, query. typing_env ) )
95106 . next ( )
@@ -320,6 +331,30 @@ enum DtorType {
320331 Significant ,
321332}
322333
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+
323358// This is a helper function for `adt_drop_tys` and `adt_significant_drop_tys`.
324359// Depending on the implantation of `adt_has_dtor`, it is used to check if the
325360// ADT has a destructor or if the ADT only has a significant destructor. For
@@ -329,8 +364,7 @@ fn drop_tys_helper<'tcx>(
329364 ty : Ty < ' tcx > ,
330365 typing_env : ty:: TypingEnv < ' tcx > ,
331366 adt_has_dtor : impl Fn ( ty:: AdtDef < ' tcx > ) -> Option < DtorType > ,
332- only_significant : bool ,
333- exhaustive : bool ,
367+ options : DropTysOptions ,
334368) -> impl Iterator < Item = NeedsDropResult < Ty < ' tcx > > > {
335369 fn with_query_cache < ' tcx > (
336370 tcx : TyCtxt < ' tcx > ,
@@ -353,6 +387,24 @@ fn drop_tys_helper<'tcx>(
353387 if adt_def. is_manually_drop ( ) {
354388 debug ! ( "drop_tys_helper: `{:?}` is manually drop" , adt_def) ;
355389 Ok ( Vec :: new ( ) )
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+ _ => {
404+ bug ! ( "drop_tys_helper: `Box` has unexpected generic args: {args:?}" ) ;
405+ }
406+ } ;
407+ Ok ( box_components)
356408 } else if let Some ( dtor_info) = adt_has_dtor ( adt_def) {
357409 match dtor_info {
358410 DtorType :: Significant => {
@@ -380,7 +432,7 @@ fn drop_tys_helper<'tcx>(
380432 ) ;
381433 r
382434 } ) ;
383- if only_significant {
435+ if options . only_significant {
384436 // We can't recurse through the query system here because we might induce a cycle
385437 Ok ( field_tys. collect ( ) )
386438 } else {
@@ -394,7 +446,7 @@ fn drop_tys_helper<'tcx>(
394446 . map ( |v| v. into_iter ( ) )
395447 } ;
396448
397- NeedsDropTypes :: new ( tcx, typing_env, ty, exhaustive, adt_components)
449+ NeedsDropTypes :: new ( tcx, typing_env, ty, options . exhaustive , adt_components)
398450}
399451
400452fn adt_consider_insignificant_dtor < ' tcx > (
@@ -433,8 +485,7 @@ fn adt_drop_tys<'tcx>(
433485 tcx. type_of ( def_id) . instantiate_identity ( ) . skip_norm_wip ( ) ,
434486 ty:: TypingEnv :: non_body_analysis ( tcx, def_id) ,
435487 adt_has_dtor,
436- false ,
437- false ,
488+ DropTysOptions :: default ( ) ,
438489 )
439490 . collect :: < Result < Vec < _ > , _ > > ( )
440491 . map ( |components| tcx. mk_type_list ( & components) )
@@ -453,8 +504,7 @@ fn adt_async_drop_tys<'tcx>(
453504 tcx. type_of ( def_id) . instantiate_identity ( ) . skip_norm_wip ( ) ,
454505 ty:: TypingEnv :: non_body_analysis ( tcx, def_id) ,
455506 adt_has_dtor,
456- false ,
457- false ,
507+ DropTysOptions :: default ( ) . recurse_into_box_for_async_drop ( ) ,
458508 )
459509 . collect :: < Result < Vec < _ > , _ > > ( )
460510 . map ( |components| tcx. mk_type_list ( & components) )
@@ -472,8 +522,7 @@ fn adt_significant_drop_tys(
472522 tcx. type_of ( def_id) . instantiate_identity ( ) . skip_norm_wip ( ) , // identical to `tcx.make_adt(def, identity_args)`
473523 ty:: TypingEnv :: non_body_analysis ( tcx, def_id) ,
474524 adt_consider_insignificant_dtor ( tcx) ,
475- true ,
476- false ,
525+ DropTysOptions :: default ( ) . only_significant ( ) ,
477526 )
478527 . collect :: < Result < Vec < _ > , _ > > ( )
479528 . map ( |components| tcx. mk_type_list ( & components) )
@@ -490,8 +539,7 @@ fn list_significant_drop_tys<'tcx>(
490539 key. value ,
491540 key. typing_env ,
492541 adt_consider_insignificant_dtor ( tcx) ,
493- true ,
494- true ,
542+ DropTysOptions :: default ( ) . only_significant ( ) . exhaustive ( ) ,
495543 )
496544 . filter_map ( |res| res. ok ( ) )
497545 . collect :: < Vec < _ > > ( ) ,
0 commit comments