@@ -1291,17 +1291,31 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
12911291 }
12921292}
12931293
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+
12941311bitflags ! {
12951312 flags AdtFlags : u32 {
12961313 const NO_ADT_FLAGS = 0 ,
12971314 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 ,
13051319 }
13061320}
13071321
@@ -1343,8 +1357,7 @@ pub struct FieldDef {
13431357pub struct AdtDef {
13441358 pub did : DefId ,
13451359 pub variants : Vec < VariantDef > ,
1346- destructor : Cell < Option < DefId > > ,
1347- flags : Cell < AdtFlags > ,
1360+ flags : AdtFlags ,
13481361 pub repr : ReprOptions ,
13491362}
13501363
@@ -1436,32 +1449,24 @@ impl<'a, 'gcx, 'tcx> AdtDef {
14361449 AdtDef {
14371450 did : did,
14381451 variants : variants,
1439- flags : Cell :: new ( flags) ,
1440- destructor : Cell :: new ( None ) ,
1452+ flags : flags,
14411453 repr : repr,
14421454 }
14431455 }
14441456
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-
14521457 #[ inline]
14531458 pub fn is_struct ( & self ) -> bool {
14541459 !self . is_union ( ) && !self . is_enum ( )
14551460 }
14561461
14571462 #[ inline]
14581463 pub fn is_union ( & self ) -> bool {
1459- self . flags . get ( ) . intersects ( AdtFlags :: IS_UNION )
1464+ self . flags . intersects ( AdtFlags :: IS_UNION )
14601465 }
14611466
14621467 #[ inline]
14631468 pub fn is_enum ( & self ) -> bool {
1464- self . flags . get ( ) . intersects ( AdtFlags :: IS_ENUM )
1469+ self . flags . intersects ( AdtFlags :: IS_ENUM )
14651470 }
14661471
14671472 /// Returns the kind of the ADT - Struct or Enum.
@@ -1497,29 +1502,26 @@ impl<'a, 'gcx, 'tcx> AdtDef {
14971502 /// alive; Otherwise, only the contents are required to be.
14981503 #[ inline]
14991504 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 )
15041506 }
15051507
15061508 /// Returns whether this type is #[fundamental] for the purposes
15071509 /// of coherence checking.
15081510 #[ inline]
15091511 pub fn is_fundamental ( & self ) -> bool {
1510- self . flags . get ( ) . intersects ( AdtFlags :: IS_FUNDAMENTAL )
1512+ self . flags . intersects ( AdtFlags :: IS_FUNDAMENTAL )
15111513 }
15121514
15131515 /// Returns true if this is PhantomData<T>.
15141516 #[ inline]
15151517 pub fn is_phantom_data ( & self ) -> bool {
1516- self . flags . get ( ) . intersects ( AdtFlags :: IS_PHANTOM_DATA )
1518+ self . flags . intersects ( AdtFlags :: IS_PHANTOM_DATA )
15171519 }
15181520
15191521 /// Returns true if this is Box<T>.
15201522 #[ inline]
15211523 pub fn is_box ( & self ) -> bool {
1522- self . flags . get ( ) . intersects ( AdtFlags :: IS_BOX )
1524+ self . flags . intersects ( AdtFlags :: IS_BOX )
15231525 }
15241526
15251527 /// Returns whether this type has a destructor.
@@ -1579,38 +1581,6 @@ impl<'a, 'gcx, 'tcx> AdtDef {
15791581 }
15801582 }
15811583
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-
16141584 pub fn discriminants ( & ' a self , tcx : TyCtxt < ' a , ' gcx , ' tcx > )
16151585 -> impl Iterator < Item =ConstInt > + ' a {
16161586 let repr_type = self . repr . discr_type ( ) ;
@@ -1632,6 +1602,10 @@ impl<'a, 'gcx, 'tcx> AdtDef {
16321602 } )
16331603 }
16341604
1605+ pub fn destructor ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> Option < Destructor > {
1606+ queries:: adt_destructor:: get ( tcx, DUMMY_SP , self . did )
1607+ }
1608+
16351609 /// Returns a simpler type such that `Self: Sized` if and only
16361610 /// if that type is Sized, or `TyErr` if this type is recursive.
16371611 ///
0 commit comments