@@ -1306,8 +1306,7 @@ impl<'tcx> Ty<'tcx> {
1306
1306
/// Checks whether values of this type `T` implements the `AsyncDrop`
1307
1307
/// trait.
1308
1308
pub fn has_surface_async_drop ( self , tcx : TyCtxt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> bool {
1309
- self . trivially_has_surface_async_drop ( )
1310
- && tcx. has_surface_async_drop_raw ( param_env. and ( self ) )
1309
+ self . could_have_surface_async_drop ( ) && tcx. has_surface_async_drop_raw ( param_env. and ( self ) )
1311
1310
}
1312
1311
1313
1312
/// Fast path helper for testing if a type has `AsyncDrop`
@@ -1316,52 +1315,68 @@ impl<'tcx> Ty<'tcx> {
1316
1315
/// Returning `false` means the type is known to not have `AsyncDrop`
1317
1316
/// implementation. Returning `true` means nothing -- could be
1318
1317
/// `AsyncDrop`, might not be.
1319
- fn trivially_has_surface_async_drop ( self ) -> bool {
1320
- match self . kind ( ) {
1321
- ty:: Int ( _)
1322
- | ty:: Uint ( _)
1323
- | ty:: Float ( _)
1324
- | ty:: Bool
1325
- | ty:: Char
1326
- | ty:: Str
1327
- | ty:: Never
1328
- | ty:: Ref ( ..)
1329
- | ty:: RawPtr ( _, _)
1330
- | ty:: FnDef ( ..)
1331
- | ty:: FnPtr ( _)
1332
- | ty:: Error ( _)
1333
- | ty:: Tuple ( _)
1334
- | ty:: Slice ( _)
1335
- | ty:: Array ( _, _)
1336
- | ty:: Closure ( ..)
1337
- | ty:: CoroutineClosure ( ..)
1338
- | ty:: Coroutine ( ..)
1339
- | ty:: CoroutineWitness ( ..)
1340
- | ty:: Pat ( ..) => false ,
1341
- ty:: Adt ( ..)
1342
- | ty:: Bound ( ..)
1343
- | ty:: Dynamic ( ..)
1344
- | ty:: Foreign ( _)
1345
- | ty:: Infer ( _)
1346
- | ty:: Alias ( ..)
1347
- | ty:: Param ( _)
1348
- | ty:: Placeholder ( _) => true ,
1349
- }
1318
+ fn could_have_surface_async_drop ( self ) -> bool {
1319
+ !self . is_async_destructor_trivially_noop ( )
1320
+ && !matches ! (
1321
+ self . kind( ) ,
1322
+ ty:: Tuple ( _)
1323
+ | ty:: Slice ( _)
1324
+ | ty:: Array ( _, _)
1325
+ | ty:: Closure ( ..)
1326
+ | ty:: CoroutineClosure ( ..)
1327
+ | ty:: Coroutine ( ..)
1328
+ )
1350
1329
}
1351
1330
1352
1331
/// Checks whether values of this type `T` implements the `AsyncDrop`
1353
1332
/// trait.
1354
1333
pub fn has_surface_drop ( self , tcx : TyCtxt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> bool {
1355
- self . trivially_has_surface_drop ( ) && tcx. has_surface_drop_raw ( param_env. and ( self ) )
1334
+ self . could_have_surface_drop ( ) && tcx. has_surface_drop_raw ( param_env. and ( self ) )
1356
1335
}
1357
1336
1358
- /// Fast path helper for testing if a type has `AsyncDrop`
1359
- /// implementation.
1337
+ /// Fast path helper for testing if a type has `Drop` implementation.
1360
1338
///
1361
- /// Returning `false` means the type is known to not have `AsyncDrop `
1339
+ /// Returning `false` means the type is known to not have `Drop `
1362
1340
/// implementation. Returning `true` means nothing -- could be
1363
- /// `AsyncDrop`, might not be.
1364
- fn trivially_has_surface_drop ( self ) -> bool {
1341
+ /// `Drop`, might not be.
1342
+ fn could_have_surface_drop ( self ) -> bool {
1343
+ self . is_async_destructor_trivially_noop ( )
1344
+ && !matches ! (
1345
+ self . kind( ) ,
1346
+ ty:: Tuple ( _)
1347
+ | ty:: Slice ( _)
1348
+ | ty:: Array ( _, _)
1349
+ | ty:: Closure ( ..)
1350
+ | ty:: CoroutineClosure ( ..)
1351
+ | ty:: Coroutine ( ..)
1352
+ )
1353
+ }
1354
+
1355
+ /// Checks whether values of this type `T` implement has noop async destructor.
1356
+ //
1357
+ // FIXME: implement optimization to make ADTs, which do not need drop,
1358
+ // to skip fields or to have noop async destructor.
1359
+ pub fn is_async_destructor_noop (
1360
+ self ,
1361
+ tcx : TyCtxt < ' tcx > ,
1362
+ param_env : ty:: ParamEnv < ' tcx > ,
1363
+ ) -> bool {
1364
+ self . is_async_destructor_trivially_noop ( )
1365
+ || if let ty:: Adt ( adt_def, _) = self . kind ( ) {
1366
+ ( adt_def. is_union ( ) || adt_def. is_payloadfree ( ) )
1367
+ && !self . has_surface_async_drop ( tcx, param_env)
1368
+ && !self . has_surface_drop ( tcx, param_env)
1369
+ } else {
1370
+ false
1371
+ }
1372
+ }
1373
+
1374
+ /// Fast path helper for testing if a type has noop async destructor.
1375
+ ///
1376
+ /// Returning `true` means the type is known to have noop async destructor
1377
+ /// implementation. Returning `true` means nothing -- could be
1378
+ /// `Drop`, might not be.
1379
+ fn is_async_destructor_trivially_noop ( self ) -> bool {
1365
1380
match self . kind ( ) {
1366
1381
ty:: Int ( _)
1367
1382
| ty:: Uint ( _)
@@ -1371,26 +1386,12 @@ impl<'tcx> Ty<'tcx> {
1371
1386
| ty:: Str
1372
1387
| ty:: Never
1373
1388
| ty:: Ref ( ..)
1374
- | ty:: RawPtr ( _ , _ )
1389
+ | ty:: RawPtr ( .. )
1375
1390
| ty:: FnDef ( ..)
1376
- | ty:: FnPtr ( _)
1377
- | ty:: Error ( _)
1378
- | ty:: Tuple ( _)
1379
- | ty:: Slice ( _)
1380
- | ty:: Array ( _, _)
1381
- | ty:: Closure ( ..)
1382
- | ty:: CoroutineClosure ( ..)
1383
- | ty:: Coroutine ( ..)
1384
- | ty:: CoroutineWitness ( ..)
1385
- | ty:: Pat ( ..) => false ,
1386
- ty:: Adt ( ..)
1387
- | ty:: Bound ( ..)
1388
- | ty:: Dynamic ( ..)
1389
- | ty:: Foreign ( _)
1390
- | ty:: Infer ( _)
1391
- | ty:: Alias ( ..)
1392
- | ty:: Param ( _)
1393
- | ty:: Placeholder ( _) => true ,
1391
+ | ty:: FnPtr ( _) => true ,
1392
+ ty:: Tuple ( tys) => tys. is_empty ( ) ,
1393
+ ty:: Adt ( adt_def, _) => adt_def. is_manually_drop ( ) ,
1394
+ _ => false ,
1394
1395
}
1395
1396
}
1396
1397
0 commit comments