@@ -1754,17 +1754,19 @@ bitflags! {
17541754 pub struct AdtFlags : u32 {
17551755 const NO_ADT_FLAGS = 0 ;
17561756 const IS_ENUM = 1 << 0 ;
1757- const IS_PHANTOM_DATA = 1 << 1 ;
1758- const IS_FUNDAMENTAL = 1 << 2 ;
1759- const IS_UNION = 1 << 3 ;
1760- const IS_BOX = 1 << 4 ;
1757+ const IS_UNION = 1 << 1 ;
1758+ const IS_STRUCT = 1 << 2 ;
1759+ const HAS_CTOR = 1 << 3 ;
1760+ const IS_PHANTOM_DATA = 1 << 4 ;
1761+ const IS_FUNDAMENTAL = 1 << 5 ;
1762+ const IS_BOX = 1 << 6 ;
17611763 /// Indicates whether the type is an `Arc`.
1762- const IS_ARC = 1 << 5 ;
1764+ const IS_ARC = 1 << 7 ;
17631765 /// Indicates whether the type is an `Rc`.
1764- const IS_RC = 1 << 6 ;
1766+ const IS_RC = 1 << 8 ;
17651767 /// Indicates whether the variant list of this ADT is `#[non_exhaustive]`.
17661768 /// (i.e., this flag is never set unless this ADT is an enum).
1767- const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 7 ;
1769+ const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 9 ;
17681770 }
17691771}
17701772
@@ -2079,31 +2081,43 @@ impl<'a, 'gcx, 'tcx> AdtDef {
20792081 repr : ReprOptions ) -> Self {
20802082 debug ! ( "AdtDef::new({:?}, {:?}, {:?}, {:?})" , did, kind, variants, repr) ;
20812083 let mut flags = AdtFlags :: NO_ADT_FLAGS ;
2084+
2085+ if kind == AdtKind :: Enum && tcx. has_attr ( did, "non_exhaustive" ) {
2086+ debug ! ( "found non-exhaustive variant list for {:?}" , did) ;
2087+ flags = flags | AdtFlags :: IS_VARIANT_LIST_NON_EXHAUSTIVE ;
2088+ }
2089+ flags |= match kind {
2090+ AdtKind :: Enum => AdtFlags :: IS_ENUM ,
2091+ AdtKind :: Union => AdtFlags :: IS_UNION ,
2092+ AdtKind :: Struct => AdtFlags :: IS_STRUCT ,
2093+ } ;
2094+
2095+ if let AdtKind :: Struct = kind {
2096+ let variant_def = & variants[ VariantIdx :: new ( 0 ) ] ;
2097+ let def_key = tcx. def_key ( variant_def. did ) ;
2098+ match def_key. disambiguated_data . data {
2099+ DefPathData :: StructCtor => flags |= AdtFlags :: HAS_CTOR ,
2100+ _ => ( ) ,
2101+ }
2102+ }
2103+
20822104 let attrs = tcx. get_attrs ( did) ;
20832105 if attr:: contains_name ( & attrs, "fundamental" ) {
2084- flags = flags | AdtFlags :: IS_FUNDAMENTAL ;
2106+ flags |= AdtFlags :: IS_FUNDAMENTAL ;
20852107 }
20862108 if Some ( did) == tcx. lang_items ( ) . phantom_data ( ) {
2087- flags = flags | AdtFlags :: IS_PHANTOM_DATA ;
2109+ flags |= AdtFlags :: IS_PHANTOM_DATA ;
20882110 }
20892111 if Some ( did) == tcx. lang_items ( ) . owned_box ( ) {
2090- flags = flags | AdtFlags :: IS_BOX ;
2112+ flags |= AdtFlags :: IS_BOX ;
20912113 }
20922114 if Some ( did) == tcx. lang_items ( ) . arc ( ) {
2093- flags = flags | AdtFlags :: IS_ARC ;
2115+ flags |= AdtFlags :: IS_ARC ;
20942116 }
20952117 if Some ( did) == tcx. lang_items ( ) . rc ( ) {
2096- flags = flags | AdtFlags :: IS_RC ;
2097- }
2098- if kind == AdtKind :: Enum && tcx. has_attr ( did, "non_exhaustive" ) {
2099- debug ! ( "found non-exhaustive variant list for {:?}" , did) ;
2100- flags = flags | AdtFlags :: IS_VARIANT_LIST_NON_EXHAUSTIVE ;
2101- }
2102- match kind {
2103- AdtKind :: Enum => flags = flags | AdtFlags :: IS_ENUM ,
2104- AdtKind :: Union => flags = flags | AdtFlags :: IS_UNION ,
2105- AdtKind :: Struct => { }
2118+ flags |= AdtFlags :: IS_RC ;
21062119 }
2120+
21072121 AdtDef {
21082122 did,
21092123 variants,
@@ -2114,25 +2128,25 @@ impl<'a, 'gcx, 'tcx> AdtDef {
21142128
21152129 #[ inline]
21162130 pub fn is_struct ( & self ) -> bool {
2117- ! self . is_union ( ) && ! self . is_enum ( )
2131+ self . flags . contains ( AdtFlags :: IS_STRUCT )
21182132 }
21192133
21202134 #[ inline]
21212135 pub fn is_union ( & self ) -> bool {
2122- self . flags . intersects ( AdtFlags :: IS_UNION )
2136+ self . flags . contains ( AdtFlags :: IS_UNION )
21232137 }
21242138
21252139 #[ inline]
21262140 pub fn is_enum ( & self ) -> bool {
2127- self . flags . intersects ( AdtFlags :: IS_ENUM )
2141+ self . flags . contains ( AdtFlags :: IS_ENUM )
21282142 }
21292143
21302144 #[ inline]
21312145 pub fn is_variant_list_non_exhaustive ( & self ) -> bool {
2132- self . flags . intersects ( AdtFlags :: IS_VARIANT_LIST_NON_EXHAUSTIVE )
2146+ self . flags . contains ( AdtFlags :: IS_VARIANT_LIST_NON_EXHAUSTIVE )
21332147 }
21342148
2135- /// Returns the kind of the ADT - Struct or Enum .
2149+ /// Returns the kind of the ADT.
21362150 #[ inline]
21372151 pub fn adt_kind ( & self ) -> AdtKind {
21382152 if self . is_enum ( ) {
@@ -2161,33 +2175,39 @@ impl<'a, 'gcx, 'tcx> AdtDef {
21612175 }
21622176 }
21632177
2164- /// Returns whether this type is #[fundamental] for the purposes
2178+ /// If this function returns `true`, it implies that `is_struct` must return `true`.
2179+ #[ inline]
2180+ pub fn has_ctor ( & self ) -> bool {
2181+ self . flags . contains ( AdtFlags :: HAS_CTOR )
2182+ }
2183+
2184+ /// Returns whether this type is `#[fundamental]` for the purposes
21652185 /// of coherence checking.
21662186 #[ inline]
21672187 pub fn is_fundamental ( & self ) -> bool {
2168- self . flags . intersects ( AdtFlags :: IS_FUNDAMENTAL )
2188+ self . flags . contains ( AdtFlags :: IS_FUNDAMENTAL )
21692189 }
21702190
21712191 /// Returns `true` if this is PhantomData<T>.
21722192 #[ inline]
21732193 pub fn is_phantom_data ( & self ) -> bool {
2174- self . flags . intersects ( AdtFlags :: IS_PHANTOM_DATA )
2194+ self . flags . contains ( AdtFlags :: IS_PHANTOM_DATA )
21752195 }
21762196
21772197 /// Returns `true` if this is `Arc<T>`.
21782198 pub fn is_arc ( & self ) -> bool {
2179- self . flags . intersects ( AdtFlags :: IS_ARC )
2199+ self . flags . contains ( AdtFlags :: IS_ARC )
21802200 }
21812201
21822202 /// Returns `true` if this is `Rc<T>`.
21832203 pub fn is_rc ( & self ) -> bool {
2184- self . flags . intersects ( AdtFlags :: IS_RC )
2204+ self . flags . contains ( AdtFlags :: IS_RC )
21852205 }
21862206
21872207 /// Returns `true` if this is Box<T>.
21882208 #[ inline]
21892209 pub fn is_box ( & self ) -> bool {
2190- self . flags . intersects ( AdtFlags :: IS_BOX )
2210+ self . flags . contains ( AdtFlags :: IS_BOX )
21912211 }
21922212
21932213 /// Returns whether this type has a destructor.
0 commit comments