@@ -1273,17 +1273,31 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
12731273 }
12741274}
12751275
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+
12761293bitflags ! {
12771294 flags AdtFlags : u32 {
12781295 const NO_ADT_FLAGS = 0 ,
12791296 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 ,
12871301 }
12881302}
12891303
@@ -1325,8 +1339,7 @@ pub struct FieldDef {
13251339pub struct AdtDef {
13261340 pub did : DefId ,
13271341 pub variants : Vec < VariantDef > ,
1328- destructor : Cell < Option < DefId > > ,
1329- flags : Cell < AdtFlags > ,
1342+ flags : AdtFlags ,
13301343 pub repr : ReprOptions ,
13311344}
13321345
@@ -1425,32 +1438,24 @@ impl<'a, 'gcx, 'tcx> AdtDef {
14251438 AdtDef {
14261439 did : did,
14271440 variants : variants,
1428- flags : Cell :: new ( flags) ,
1429- destructor : Cell :: new ( None ) ,
1441+ flags : flags,
14301442 repr : repr,
14311443 }
14321444 }
14331445
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-
14411446 #[ inline]
14421447 pub fn is_struct ( & self ) -> bool {
14431448 !self . is_union ( ) && !self . is_enum ( )
14441449 }
14451450
14461451 #[ inline]
14471452 pub fn is_union ( & self ) -> bool {
1448- self . flags . get ( ) . intersects ( AdtFlags :: IS_UNION )
1453+ self . flags . intersects ( AdtFlags :: IS_UNION )
14491454 }
14501455
14511456 #[ inline]
14521457 pub fn is_enum ( & self ) -> bool {
1453- self . flags . get ( ) . intersects ( AdtFlags :: IS_ENUM )
1458+ self . flags . intersects ( AdtFlags :: IS_ENUM )
14541459 }
14551460
14561461 /// Returns the kind of the ADT - Struct or Enum.
@@ -1486,29 +1491,26 @@ impl<'a, 'gcx, 'tcx> AdtDef {
14861491 /// alive; Otherwise, only the contents are required to be.
14871492 #[ inline]
14881493 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 )
14931495 }
14941496
14951497 /// Returns whether this type is #[fundamental] for the purposes
14961498 /// of coherence checking.
14971499 #[ inline]
14981500 pub fn is_fundamental ( & self ) -> bool {
1499- self . flags . get ( ) . intersects ( AdtFlags :: IS_FUNDAMENTAL )
1501+ self . flags . intersects ( AdtFlags :: IS_FUNDAMENTAL )
15001502 }
15011503
15021504 /// Returns true if this is PhantomData<T>.
15031505 #[ inline]
15041506 pub fn is_phantom_data ( & self ) -> bool {
1505- self . flags . get ( ) . intersects ( AdtFlags :: IS_PHANTOM_DATA )
1507+ self . flags . intersects ( AdtFlags :: IS_PHANTOM_DATA )
15061508 }
15071509
15081510 /// Returns true if this is Box<T>.
15091511 #[ inline]
15101512 pub fn is_box ( & self ) -> bool {
1511- self . flags . get ( ) . intersects ( AdtFlags :: IS_BOX )
1513+ self . flags . intersects ( AdtFlags :: IS_BOX )
15121514 }
15131515
15141516 /// Returns whether this type has a destructor.
@@ -1568,38 +1570,6 @@ impl<'a, 'gcx, 'tcx> AdtDef {
15681570 }
15691571 }
15701572
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-
16031573 pub fn discriminants ( & ' a self , tcx : TyCtxt < ' a , ' gcx , ' tcx > )
16041574 -> impl Iterator < Item =ConstInt > + ' a {
16051575 let repr_type = self . repr . discr_type ( ) ;
@@ -1621,6 +1591,10 @@ impl<'a, 'gcx, 'tcx> AdtDef {
16211591 } )
16221592 }
16231593
1594+ pub fn destructor ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> Option < Destructor > {
1595+ queries:: adt_destructor:: get ( tcx, DUMMY_SP , self . did )
1596+ }
1597+
16241598 /// Returns a simpler type such that `Self: Sized` if and only
16251599 /// if that type is Sized, or `TyErr` if this type is recursive.
16261600 ///
0 commit comments