@@ -1273,17 +1273,31 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
1273
1273
}
1274
1274
}
1275
1275
1276
+ #[ derive( Copy , Clone , Debug ) ]
1277
+ pub struct Destructor {
1278
+ /// The def-id of the destructor method
1279
+ pub did : DefId ,
1280
+ /// Invoking the destructor of a dtorck type during usual cleanup
1281
+ /// (e.g. the glue emitted for stack unwinding) requires all
1282
+ /// lifetimes in the type-structure of `adt` to strictly outlive
1283
+ /// the adt value itself.
1284
+ ///
1285
+ /// If `adt` is not dtorck, then the adt's destructor can be
1286
+ /// invoked even when there are lifetimes in the type-structure of
1287
+ /// `adt` that do not strictly outlive the adt value itself.
1288
+ /// (This allows programs to make cyclic structures without
1289
+ /// resorting to unasfe means; see RFCs 769 and 1238).
1290
+ pub is_dtorck : bool ,
1291
+ }
1292
+
1276
1293
bitflags ! {
1277
1294
flags AdtFlags : u32 {
1278
1295
const NO_ADT_FLAGS = 0 ,
1279
1296
const IS_ENUM = 1 << 0 ,
1280
- const IS_DTORCK = 1 << 1 , // is this a dtorck type?
1281
- const IS_DTORCK_VALID = 1 << 2 ,
1282
- const IS_PHANTOM_DATA = 1 << 3 ,
1283
- const IS_FUNDAMENTAL = 1 << 4 ,
1284
- const IS_UNION = 1 << 5 ,
1285
- const IS_BOX = 1 << 6 ,
1286
- const IS_DTOR_VALID = 1 << 7 ,
1297
+ const IS_PHANTOM_DATA = 1 << 1 ,
1298
+ const IS_FUNDAMENTAL = 1 << 2 ,
1299
+ const IS_UNION = 1 << 3 ,
1300
+ const IS_BOX = 1 << 4 ,
1287
1301
}
1288
1302
}
1289
1303
@@ -1325,8 +1339,7 @@ pub struct FieldDef {
1325
1339
pub struct AdtDef {
1326
1340
pub did : DefId ,
1327
1341
pub variants : Vec < VariantDef > ,
1328
- destructor : Cell < Option < DefId > > ,
1329
- flags : Cell < AdtFlags > ,
1342
+ flags : AdtFlags ,
1330
1343
pub repr : ReprOptions ,
1331
1344
}
1332
1345
@@ -1425,32 +1438,24 @@ impl<'a, 'gcx, 'tcx> AdtDef {
1425
1438
AdtDef {
1426
1439
did : did,
1427
1440
variants : variants,
1428
- flags : Cell :: new ( flags) ,
1429
- destructor : Cell :: new ( None ) ,
1441
+ flags : flags,
1430
1442
repr : repr,
1431
1443
}
1432
1444
}
1433
1445
1434
- fn calculate_dtorck ( & ' gcx self , tcx : TyCtxt ) {
1435
- if tcx. is_adt_dtorck ( self ) {
1436
- self . flags . set ( self . flags . get ( ) | AdtFlags :: IS_DTORCK ) ;
1437
- }
1438
- self . flags . set ( self . flags . get ( ) | AdtFlags :: IS_DTORCK_VALID )
1439
- }
1440
-
1441
1446
#[ inline]
1442
1447
pub fn is_struct ( & self ) -> bool {
1443
1448
!self . is_union ( ) && !self . is_enum ( )
1444
1449
}
1445
1450
1446
1451
#[ inline]
1447
1452
pub fn is_union ( & self ) -> bool {
1448
- self . flags . get ( ) . intersects ( AdtFlags :: IS_UNION )
1453
+ self . flags . intersects ( AdtFlags :: IS_UNION )
1449
1454
}
1450
1455
1451
1456
#[ inline]
1452
1457
pub fn is_enum ( & self ) -> bool {
1453
- self . flags . get ( ) . intersects ( AdtFlags :: IS_ENUM )
1458
+ self . flags . intersects ( AdtFlags :: IS_ENUM )
1454
1459
}
1455
1460
1456
1461
/// Returns the kind of the ADT - Struct or Enum.
@@ -1486,29 +1491,26 @@ impl<'a, 'gcx, 'tcx> AdtDef {
1486
1491
/// alive; Otherwise, only the contents are required to be.
1487
1492
#[ inline]
1488
1493
pub fn is_dtorck ( & ' gcx self , tcx : TyCtxt ) -> bool {
1489
- if !self . flags . get ( ) . intersects ( AdtFlags :: IS_DTORCK_VALID ) {
1490
- self . calculate_dtorck ( tcx)
1491
- }
1492
- self . flags . get ( ) . intersects ( AdtFlags :: IS_DTORCK )
1494
+ self . destructor ( tcx) . map_or ( false , |d| d. is_dtorck )
1493
1495
}
1494
1496
1495
1497
/// Returns whether this type is #[fundamental] for the purposes
1496
1498
/// of coherence checking.
1497
1499
#[ inline]
1498
1500
pub fn is_fundamental ( & self ) -> bool {
1499
- self . flags . get ( ) . intersects ( AdtFlags :: IS_FUNDAMENTAL )
1501
+ self . flags . intersects ( AdtFlags :: IS_FUNDAMENTAL )
1500
1502
}
1501
1503
1502
1504
/// Returns true if this is PhantomData<T>.
1503
1505
#[ inline]
1504
1506
pub fn is_phantom_data ( & self ) -> bool {
1505
- self . flags . get ( ) . intersects ( AdtFlags :: IS_PHANTOM_DATA )
1507
+ self . flags . intersects ( AdtFlags :: IS_PHANTOM_DATA )
1506
1508
}
1507
1509
1508
1510
/// Returns true if this is Box<T>.
1509
1511
#[ inline]
1510
1512
pub fn is_box ( & self ) -> bool {
1511
- self . flags . get ( ) . intersects ( AdtFlags :: IS_BOX )
1513
+ self . flags . intersects ( AdtFlags :: IS_BOX )
1512
1514
}
1513
1515
1514
1516
/// Returns whether this type has a destructor.
@@ -1568,38 +1570,6 @@ impl<'a, 'gcx, 'tcx> AdtDef {
1568
1570
}
1569
1571
}
1570
1572
1571
- pub fn destructor ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> Option < DefId > {
1572
- if self . flags . get ( ) . intersects ( AdtFlags :: IS_DTOR_VALID ) {
1573
- return self . destructor . get ( ) ;
1574
- }
1575
-
1576
- let dtor = self . destructor_uncached ( tcx) ;
1577
- self . destructor . set ( dtor) ;
1578
- self . flags . set ( self . flags . get ( ) | AdtFlags :: IS_DTOR_VALID ) ;
1579
-
1580
- dtor
1581
- }
1582
-
1583
- fn destructor_uncached ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> Option < DefId > {
1584
- let drop_trait = if let Some ( def_id) = tcx. lang_items . drop_trait ( ) {
1585
- def_id
1586
- } else {
1587
- return None ;
1588
- } ;
1589
-
1590
- queries:: coherent_trait:: get ( tcx, DUMMY_SP , ( LOCAL_CRATE , drop_trait) ) ;
1591
-
1592
- let mut dtor = None ;
1593
- let ty = tcx. item_type ( self . did ) ;
1594
- tcx. lookup_trait_def ( drop_trait) . for_each_relevant_impl ( tcx, ty, |def_id| {
1595
- if let Some ( item) = tcx. associated_items ( def_id) . next ( ) {
1596
- dtor = Some ( item. def_id ) ;
1597
- }
1598
- } ) ;
1599
-
1600
- dtor
1601
- }
1602
-
1603
1573
pub fn discriminants ( & ' a self , tcx : TyCtxt < ' a , ' gcx , ' tcx > )
1604
1574
-> impl Iterator < Item =ConstInt > + ' a {
1605
1575
let repr_type = self . repr . discr_type ( ) ;
@@ -1621,6 +1591,10 @@ impl<'a, 'gcx, 'tcx> AdtDef {
1621
1591
} )
1622
1592
}
1623
1593
1594
+ pub fn destructor ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> Option < Destructor > {
1595
+ queries:: adt_destructor:: get ( tcx, DUMMY_SP , self . did )
1596
+ }
1597
+
1624
1598
/// Returns a simpler type such that `Self: Sized` if and only
1625
1599
/// if that type is Sized, or `TyErr` if this type is recursive.
1626
1600
///
0 commit comments