@@ -420,6 +420,25 @@ impl<'tcx> TyCtxt<'tcx> {
420
420
Some ( ty:: AsyncDestructor { future, ctor } )
421
421
}
422
422
423
+ /// Returns async drop glue morphology for a definition. To get async drop
424
+ /// glue morphology for a type see [`Ty::async_drop_glue_morphology`].
425
+ //
426
+ // FIXME: consider making this a query
427
+ pub fn async_drop_glue_morphology ( self , did : DefId ) -> AsyncDropGlueMorphology {
428
+ let ty: Ty < ' tcx > = self . type_of ( did) . instantiate_identity ( ) ;
429
+
430
+ // Async drop glue morphology is an internal detail, so reveal_all probably
431
+ // should be fine
432
+ let param_env = ty:: ParamEnv :: reveal_all ( ) ;
433
+ if ty. needs_async_drop ( self , param_env) {
434
+ AsyncDropGlueMorphology :: Custom
435
+ } else if ty. needs_drop ( self , param_env) {
436
+ AsyncDropGlueMorphology :: DeferredDropInPlace
437
+ } else {
438
+ AsyncDropGlueMorphology :: Noop
439
+ }
440
+ }
441
+
423
442
/// Returns the set of types that are required to be alive in
424
443
/// order to run the destructor of `def` (see RFCs 769 and
425
444
/// 1238).
@@ -1176,6 +1195,18 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for WeakAliasTypeExpander<'tcx> {
1176
1195
}
1177
1196
}
1178
1197
1198
+ /// Indicates the form of `AsyncDestruct::Destructor`. Used to simplify async
1199
+ /// drop glue for types not using async drop.
1200
+ #[ derive( Clone , Copy , PartialEq , Eq , Debug ) ]
1201
+ pub enum AsyncDropGlueMorphology {
1202
+ /// Async destructor simply does nothing
1203
+ Noop ,
1204
+ /// Async destructor simply runs `drop_in_place`
1205
+ DeferredDropInPlace ,
1206
+ /// Async destructor has custom logic
1207
+ Custom ,
1208
+ }
1209
+
1179
1210
impl < ' tcx > Ty < ' tcx > {
1180
1211
/// Returns the `Size` for primitive types (bool, uint, int, char, float).
1181
1212
pub fn primitive_size ( self , tcx : TyCtxt < ' tcx > ) -> Size {
@@ -1342,27 +1373,16 @@ impl<'tcx> Ty<'tcx> {
1342
1373
}
1343
1374
}
1344
1375
1345
- /// Checks whether values of this type `T` implement has noop async destructor.
1376
+ /// Get morphology of the async drop glue, needed for types which do not
1377
+ /// use async drop. To get async drop glue morphology for a definition see
1378
+ /// [`TyCtxt::async_drop_glue_morphology`]. Used for `AsyncDestruct::Destructor`
1379
+ /// type construction.
1346
1380
//
1347
- // FIXME: implement optimization to make ADTs, which do not need drop,
1348
- // to skip fields or to have noop async destructor, use `needs_(async_)drop`
1349
- pub fn is_async_destructor_noop (
1350
- self ,
1351
- tcx : TyCtxt < ' tcx > ,
1352
- param_env : ty:: ParamEnv < ' tcx > ,
1353
- ) -> bool {
1354
- // TODO: check on the most generic version of your type
1355
- self . is_async_destructor_trivially_noop ( )
1356
- || self . needs_async_drop ( tcx, param_env)
1357
- || self . needs_drop ( tcx, param_env)
1358
- }
1359
-
1360
- /// Fast path helper for testing if a type has noop async destructor.
1361
- ///
1362
- /// Returning `true` means the type is known to have noop async destructor
1363
- /// implementation. Returning `true` means nothing -- could be
1364
- /// `Drop`, might not be.
1365
- fn is_async_destructor_trivially_noop ( self ) -> bool {
1381
+ // FIXME: implement optimization to not instantiate a certain morphology of
1382
+ // async drop glue too soon to allow per type optimizations, see array case
1383
+ // for more info. Perhaps then remove this method and use `needs_(async_)drop`
1384
+ // instead.
1385
+ pub fn async_drop_glue_morphology ( self , tcx : TyCtxt < ' tcx > ) -> AsyncDropGlueMorphology {
1366
1386
match self . kind ( ) {
1367
1387
ty:: Int ( _)
1368
1388
| ty:: Uint ( _)
@@ -1374,37 +1394,43 @@ impl<'tcx> Ty<'tcx> {
1374
1394
| ty:: Ref ( ..)
1375
1395
| ty:: RawPtr ( ..)
1376
1396
| ty:: FnDef ( ..)
1377
- | ty:: FnPtr ( _) => true ,
1378
- ty:: Tuple ( tys) => tys. is_empty ( ) ,
1379
- ty:: Adt ( adt_def, _) => adt_def. is_manually_drop ( ) ,
1380
- ty:: Bool => todo ! ( ) ,
1381
- ty:: Char => todo ! ( ) ,
1382
- ty:: Int ( _) => todo ! ( ) ,
1383
- ty:: Uint ( _) => todo ! ( ) ,
1384
- ty:: Float ( _) => todo ! ( ) ,
1385
- ty:: Adt ( _, _) => todo ! ( ) ,
1386
- ty:: Foreign ( _) => todo ! ( ) ,
1387
- ty:: Str => todo ! ( ) ,
1388
- ty:: Array ( _, _) => todo ! ( ) ,
1389
- ty:: Pat ( _, _) => todo ! ( ) ,
1390
- ty:: Slice ( _) => todo ! ( ) ,
1391
- ty:: RawPtr ( _, _) => todo ! ( ) ,
1392
- ty:: Ref ( _, _, _) => todo ! ( ) ,
1393
- ty:: FnDef ( _, _) => todo ! ( ) ,
1394
- ty:: FnPtr ( _) => todo ! ( ) ,
1395
- ty:: Dynamic ( _, _, _) => todo ! ( ) ,
1396
- ty:: Closure ( _, _) => todo ! ( ) ,
1397
- ty:: CoroutineClosure ( _, _) => todo ! ( ) ,
1398
- ty:: Coroutine ( _, _) => todo ! ( ) ,
1399
- ty:: CoroutineWitness ( _, _) => todo ! ( ) ,
1400
- ty:: Never => todo ! ( ) ,
1401
- ty:: Tuple ( _) => todo ! ( ) ,
1402
- ty:: Alias ( _, _) => todo ! ( ) ,
1403
- ty:: Param ( _) => todo ! ( ) ,
1404
- ty:: Bound ( _, _) => todo ! ( ) ,
1405
- ty:: Placeholder ( _) => todo ! ( ) ,
1406
- ty:: Infer ( _) => todo ! ( ) ,
1407
- ty:: Error ( _) => todo ! ( ) ,
1397
+ | ty:: FnPtr ( _)
1398
+ | ty:: Infer ( ty:: FreshIntTy ( _) )
1399
+ | ty:: Infer ( ty:: FreshFloatTy ( _) ) => AsyncDropGlueMorphology :: Noop ,
1400
+
1401
+ ty:: Tuple ( tys) if tys. is_empty ( ) => AsyncDropGlueMorphology :: Noop ,
1402
+ ty:: Adt ( adt_def, _) if adt_def. is_manually_drop ( ) => AsyncDropGlueMorphology :: Noop ,
1403
+
1404
+ // Foreign types can never have destructors.
1405
+ ty:: Foreign ( _) => AsyncDropGlueMorphology :: Noop ,
1406
+
1407
+ // FIXME: implement dynamic types async drops
1408
+ ty:: Error ( _) | ty:: Dynamic ( ..) => AsyncDropGlueMorphology :: DeferredDropInPlace ,
1409
+
1410
+ ty:: Tuple ( _) | ty:: Array ( _, _) | ty:: Slice ( _) => {
1411
+ // Assume worst-case scenario, because we can instantiate async
1412
+ // destructors in different orders:
1413
+ //
1414
+ // 1. Instantiate [T; N] with T = String and N = 0
1415
+ // 2. Instantiate <[String; 0] as AsyncDestruct>::Destructor
1416
+ //
1417
+ // And viceversa, thus we cannot rely on String not using async
1418
+ // drop or array having zero (0) elements
1419
+ AsyncDropGlueMorphology :: Custom
1420
+ }
1421
+ ty:: Pat ( ty, _) => ty. async_drop_glue_morphology ( tcx) ,
1422
+
1423
+ ty:: Adt ( adt_def, _) => tcx. async_drop_glue_morphology ( adt_def. did ( ) ) ,
1424
+
1425
+ ty:: Closure ( did, _)
1426
+ | ty:: CoroutineClosure ( did, _)
1427
+ | ty:: Coroutine ( did, _)
1428
+ | ty:: CoroutineWitness ( did, _) => tcx. async_drop_glue_morphology ( * did) ,
1429
+
1430
+ ty:: Alias ( ..) | ty:: Param ( _) | ty:: Bound ( ..) | ty:: Placeholder ( ..) | ty:: Infer ( _) => {
1431
+ // No specifics, but would usually mean forwarding async drop glue
1432
+ AsyncDropGlueMorphology :: Custom
1433
+ }
1408
1434
}
1409
1435
}
1410
1436
@@ -1451,7 +1477,11 @@ impl<'tcx> Ty<'tcx> {
1451
1477
/// (Note that this implies that if `ty` has an async destructor attached,
1452
1478
/// then `needs_async_drop` will definitely return `true` for `ty`.)
1453
1479
///
1454
- /// Note that this method is used to check eligible types in unions.
1480
+ /// When constructing `AsyncDestruct::Destructor` type, use
1481
+ /// [`Ty::async_drop_glue_morphology`] instead.
1482
+ //
1483
+ // FIXME(zetanumbers): Note that this method is used to check eligible types
1484
+ // in unions.
1455
1485
#[ inline]
1456
1486
pub fn needs_async_drop ( self , tcx : TyCtxt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> bool {
1457
1487
// Avoid querying in simple cases.
@@ -1647,10 +1677,13 @@ impl<'tcx> ExplicitSelf<'tcx> {
1647
1677
}
1648
1678
}
1649
1679
1650
- // FIXME(zetanumbers): make specifying asyncness explicit
1651
1680
/// Returns a list of types such that the given type needs drop if and only if
1652
1681
/// *any* of the returned types need drop. Returns `Err(AlwaysRequiresDrop)` if
1653
1682
/// this type always needs drop.
1683
+ //
1684
+ // FIXME(zetanumbers): consider replacing this with only
1685
+ // `needs_drop_components_with_async`
1686
+ #[ inline]
1654
1687
pub fn needs_drop_components < ' tcx > (
1655
1688
tcx : TyCtxt < ' tcx > ,
1656
1689
ty : Ty < ' tcx > ,
0 commit comments