@@ -1291,17 +1291,31 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
1291
1291
}
1292
1292
}
1293
1293
1294
+ #[ derive( Copy , Clone , Debug ) ]
1295
+ pub struct Destructor {
1296
+ /// The def-id of the destructor method
1297
+ pub did : DefId ,
1298
+ /// Invoking the destructor of a dtorck type during usual cleanup
1299
+ /// (e.g. the glue emitted for stack unwinding) requires all
1300
+ /// lifetimes in the type-structure of `adt` to strictly outlive
1301
+ /// the adt value itself.
1302
+ ///
1303
+ /// If `adt` is not dtorck, then the adt's destructor can be
1304
+ /// invoked even when there are lifetimes in the type-structure of
1305
+ /// `adt` that do not strictly outlive the adt value itself.
1306
+ /// (This allows programs to make cyclic structures without
1307
+ /// resorting to unasfe means; see RFCs 769 and 1238).
1308
+ pub is_dtorck : bool ,
1309
+ }
1310
+
1294
1311
bitflags ! {
1295
1312
flags AdtFlags : u32 {
1296
1313
const NO_ADT_FLAGS = 0 ,
1297
1314
const IS_ENUM = 1 << 0 ,
1298
- const IS_DTORCK = 1 << 1 , // is this a dtorck type?
1299
- const IS_DTORCK_VALID = 1 << 2 ,
1300
- const IS_PHANTOM_DATA = 1 << 3 ,
1301
- const IS_FUNDAMENTAL = 1 << 4 ,
1302
- const IS_UNION = 1 << 5 ,
1303
- const IS_BOX = 1 << 6 ,
1304
- const IS_DTOR_VALID = 1 << 7 ,
1315
+ const IS_PHANTOM_DATA = 1 << 1 ,
1316
+ const IS_FUNDAMENTAL = 1 << 2 ,
1317
+ const IS_UNION = 1 << 3 ,
1318
+ const IS_BOX = 1 << 4 ,
1305
1319
}
1306
1320
}
1307
1321
@@ -1343,8 +1357,7 @@ pub struct FieldDef {
1343
1357
pub struct AdtDef {
1344
1358
pub did : DefId ,
1345
1359
pub variants : Vec < VariantDef > ,
1346
- destructor : Cell < Option < DefId > > ,
1347
- flags : Cell < AdtFlags > ,
1360
+ flags : AdtFlags ,
1348
1361
pub repr : ReprOptions ,
1349
1362
}
1350
1363
@@ -1436,32 +1449,24 @@ impl<'a, 'gcx, 'tcx> AdtDef {
1436
1449
AdtDef {
1437
1450
did : did,
1438
1451
variants : variants,
1439
- flags : Cell :: new ( flags) ,
1440
- destructor : Cell :: new ( None ) ,
1452
+ flags : flags,
1441
1453
repr : repr,
1442
1454
}
1443
1455
}
1444
1456
1445
- fn calculate_dtorck ( & ' gcx self , tcx : TyCtxt ) {
1446
- if tcx. is_adt_dtorck ( self ) {
1447
- self . flags . set ( self . flags . get ( ) | AdtFlags :: IS_DTORCK ) ;
1448
- }
1449
- self . flags . set ( self . flags . get ( ) | AdtFlags :: IS_DTORCK_VALID )
1450
- }
1451
-
1452
1457
#[ inline]
1453
1458
pub fn is_struct ( & self ) -> bool {
1454
1459
!self . is_union ( ) && !self . is_enum ( )
1455
1460
}
1456
1461
1457
1462
#[ inline]
1458
1463
pub fn is_union ( & self ) -> bool {
1459
- self . flags . get ( ) . intersects ( AdtFlags :: IS_UNION )
1464
+ self . flags . intersects ( AdtFlags :: IS_UNION )
1460
1465
}
1461
1466
1462
1467
#[ inline]
1463
1468
pub fn is_enum ( & self ) -> bool {
1464
- self . flags . get ( ) . intersects ( AdtFlags :: IS_ENUM )
1469
+ self . flags . intersects ( AdtFlags :: IS_ENUM )
1465
1470
}
1466
1471
1467
1472
/// Returns the kind of the ADT - Struct or Enum.
@@ -1497,29 +1502,26 @@ impl<'a, 'gcx, 'tcx> AdtDef {
1497
1502
/// alive; Otherwise, only the contents are required to be.
1498
1503
#[ inline]
1499
1504
pub fn is_dtorck ( & ' gcx self , tcx : TyCtxt ) -> bool {
1500
- if !self . flags . get ( ) . intersects ( AdtFlags :: IS_DTORCK_VALID ) {
1501
- self . calculate_dtorck ( tcx)
1502
- }
1503
- self . flags . get ( ) . intersects ( AdtFlags :: IS_DTORCK )
1505
+ self . destructor ( tcx) . map_or ( false , |d| d. is_dtorck )
1504
1506
}
1505
1507
1506
1508
/// Returns whether this type is #[fundamental] for the purposes
1507
1509
/// of coherence checking.
1508
1510
#[ inline]
1509
1511
pub fn is_fundamental ( & self ) -> bool {
1510
- self . flags . get ( ) . intersects ( AdtFlags :: IS_FUNDAMENTAL )
1512
+ self . flags . intersects ( AdtFlags :: IS_FUNDAMENTAL )
1511
1513
}
1512
1514
1513
1515
/// Returns true if this is PhantomData<T>.
1514
1516
#[ inline]
1515
1517
pub fn is_phantom_data ( & self ) -> bool {
1516
- self . flags . get ( ) . intersects ( AdtFlags :: IS_PHANTOM_DATA )
1518
+ self . flags . intersects ( AdtFlags :: IS_PHANTOM_DATA )
1517
1519
}
1518
1520
1519
1521
/// Returns true if this is Box<T>.
1520
1522
#[ inline]
1521
1523
pub fn is_box ( & self ) -> bool {
1522
- self . flags . get ( ) . intersects ( AdtFlags :: IS_BOX )
1524
+ self . flags . intersects ( AdtFlags :: IS_BOX )
1523
1525
}
1524
1526
1525
1527
/// Returns whether this type has a destructor.
@@ -1579,38 +1581,6 @@ impl<'a, 'gcx, 'tcx> AdtDef {
1579
1581
}
1580
1582
}
1581
1583
1582
- pub fn destructor ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> Option < DefId > {
1583
- if self . flags . get ( ) . intersects ( AdtFlags :: IS_DTOR_VALID ) {
1584
- return self . destructor . get ( ) ;
1585
- }
1586
-
1587
- let dtor = self . destructor_uncached ( tcx) ;
1588
- self . destructor . set ( dtor) ;
1589
- self . flags . set ( self . flags . get ( ) | AdtFlags :: IS_DTOR_VALID ) ;
1590
-
1591
- dtor
1592
- }
1593
-
1594
- fn destructor_uncached ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> Option < DefId > {
1595
- let drop_trait = if let Some ( def_id) = tcx. lang_items . drop_trait ( ) {
1596
- def_id
1597
- } else {
1598
- return None ;
1599
- } ;
1600
-
1601
- queries:: coherent_trait:: get ( tcx, DUMMY_SP , ( LOCAL_CRATE , drop_trait) ) ;
1602
-
1603
- let mut dtor = None ;
1604
- let ty = tcx. item_type ( self . did ) ;
1605
- tcx. lookup_trait_def ( drop_trait) . for_each_relevant_impl ( tcx, ty, |def_id| {
1606
- if let Some ( item) = tcx. associated_items ( def_id) . next ( ) {
1607
- dtor = Some ( item. def_id ) ;
1608
- }
1609
- } ) ;
1610
-
1611
- dtor
1612
- }
1613
-
1614
1584
pub fn discriminants ( & ' a self , tcx : TyCtxt < ' a , ' gcx , ' tcx > )
1615
1585
-> impl Iterator < Item =ConstInt > + ' a {
1616
1586
let repr_type = self . repr . discr_type ( ) ;
@@ -1632,6 +1602,10 @@ impl<'a, 'gcx, 'tcx> AdtDef {
1632
1602
} )
1633
1603
}
1634
1604
1605
+ pub fn destructor ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> Option < Destructor > {
1606
+ queries:: adt_destructor:: get ( tcx, DUMMY_SP , self . did )
1607
+ }
1608
+
1635
1609
/// Returns a simpler type such that `Self: Sized` if and only
1636
1610
/// if that type is Sized, or `TyErr` if this type is recursive.
1637
1611
///
0 commit comments