@@ -1306,8 +1306,7 @@ impl<'tcx> Ty<'tcx> {
13061306 /// Checks whether values of this type `T` implements the `AsyncDrop`
13071307 /// trait.
13081308 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 ) )
13111310 }
13121311
13131312 /// Fast path helper for testing if a type has `AsyncDrop`
@@ -1316,52 +1315,68 @@ impl<'tcx> Ty<'tcx> {
13161315 /// Returning `false` means the type is known to not have `AsyncDrop`
13171316 /// implementation. Returning `true` means nothing -- could be
13181317 /// `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+ )
13501329 }
13511330
13521331 /// Checks whether values of this type `T` implements the `AsyncDrop`
13531332 /// trait.
13541333 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 ) )
13561335 }
13571336
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.
13601338 ///
1361- /// Returning `false` means the type is known to not have `AsyncDrop `
1339+ /// Returning `false` means the type is known to not have `Drop `
13621340 /// 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 {
13651380 match self . kind ( ) {
13661381 ty:: Int ( _)
13671382 | ty:: Uint ( _)
@@ -1371,26 +1386,12 @@ impl<'tcx> Ty<'tcx> {
13711386 | ty:: Str
13721387 | ty:: Never
13731388 | ty:: Ref ( ..)
1374- | ty:: RawPtr ( _ , _ )
1389+ | ty:: RawPtr ( .. )
13751390 | 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 ,
13941395 }
13951396 }
13961397
0 commit comments