@@ -1754,17 +1754,19 @@ bitflags! {
1754
1754
pub struct AdtFlags : u32 {
1755
1755
const NO_ADT_FLAGS = 0 ;
1756
1756
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 ;
1761
1763
/// Indicates whether the type is an `Arc`.
1762
- const IS_ARC = 1 << 5 ;
1764
+ const IS_ARC = 1 << 7 ;
1763
1765
/// Indicates whether the type is an `Rc`.
1764
- const IS_RC = 1 << 6 ;
1766
+ const IS_RC = 1 << 8 ;
1765
1767
/// Indicates whether the variant list of this ADT is `#[non_exhaustive]`.
1766
1768
/// (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 ;
1768
1770
}
1769
1771
}
1770
1772
@@ -2079,31 +2081,43 @@ impl<'a, 'gcx, 'tcx> AdtDef {
2079
2081
repr : ReprOptions ) -> Self {
2080
2082
debug ! ( "AdtDef::new({:?}, {:?}, {:?}, {:?})" , did, kind, variants, repr) ;
2081
2083
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
+
2082
2104
let attrs = tcx. get_attrs ( did) ;
2083
2105
if attr:: contains_name ( & attrs, "fundamental" ) {
2084
- flags = flags | AdtFlags :: IS_FUNDAMENTAL ;
2106
+ flags |= AdtFlags :: IS_FUNDAMENTAL ;
2085
2107
}
2086
2108
if Some ( did) == tcx. lang_items ( ) . phantom_data ( ) {
2087
- flags = flags | AdtFlags :: IS_PHANTOM_DATA ;
2109
+ flags |= AdtFlags :: IS_PHANTOM_DATA ;
2088
2110
}
2089
2111
if Some ( did) == tcx. lang_items ( ) . owned_box ( ) {
2090
- flags = flags | AdtFlags :: IS_BOX ;
2112
+ flags |= AdtFlags :: IS_BOX ;
2091
2113
}
2092
2114
if Some ( did) == tcx. lang_items ( ) . arc ( ) {
2093
- flags = flags | AdtFlags :: IS_ARC ;
2115
+ flags |= AdtFlags :: IS_ARC ;
2094
2116
}
2095
2117
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 ;
2106
2119
}
2120
+
2107
2121
AdtDef {
2108
2122
did,
2109
2123
variants,
@@ -2114,25 +2128,25 @@ impl<'a, 'gcx, 'tcx> AdtDef {
2114
2128
2115
2129
#[ inline]
2116
2130
pub fn is_struct ( & self ) -> bool {
2117
- ! self . is_union ( ) && ! self . is_enum ( )
2131
+ self . flags . contains ( AdtFlags :: IS_STRUCT )
2118
2132
}
2119
2133
2120
2134
#[ inline]
2121
2135
pub fn is_union ( & self ) -> bool {
2122
- self . flags . intersects ( AdtFlags :: IS_UNION )
2136
+ self . flags . contains ( AdtFlags :: IS_UNION )
2123
2137
}
2124
2138
2125
2139
#[ inline]
2126
2140
pub fn is_enum ( & self ) -> bool {
2127
- self . flags . intersects ( AdtFlags :: IS_ENUM )
2141
+ self . flags . contains ( AdtFlags :: IS_ENUM )
2128
2142
}
2129
2143
2130
2144
#[ inline]
2131
2145
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 )
2133
2147
}
2134
2148
2135
- /// Returns the kind of the ADT - Struct or Enum .
2149
+ /// Returns the kind of the ADT.
2136
2150
#[ inline]
2137
2151
pub fn adt_kind ( & self ) -> AdtKind {
2138
2152
if self . is_enum ( ) {
@@ -2161,33 +2175,39 @@ impl<'a, 'gcx, 'tcx> AdtDef {
2161
2175
}
2162
2176
}
2163
2177
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
2165
2185
/// of coherence checking.
2166
2186
#[ inline]
2167
2187
pub fn is_fundamental ( & self ) -> bool {
2168
- self . flags . intersects ( AdtFlags :: IS_FUNDAMENTAL )
2188
+ self . flags . contains ( AdtFlags :: IS_FUNDAMENTAL )
2169
2189
}
2170
2190
2171
2191
/// Returns `true` if this is PhantomData<T>.
2172
2192
#[ inline]
2173
2193
pub fn is_phantom_data ( & self ) -> bool {
2174
- self . flags . intersects ( AdtFlags :: IS_PHANTOM_DATA )
2194
+ self . flags . contains ( AdtFlags :: IS_PHANTOM_DATA )
2175
2195
}
2176
2196
2177
2197
/// Returns `true` if this is `Arc<T>`.
2178
2198
pub fn is_arc ( & self ) -> bool {
2179
- self . flags . intersects ( AdtFlags :: IS_ARC )
2199
+ self . flags . contains ( AdtFlags :: IS_ARC )
2180
2200
}
2181
2201
2182
2202
/// Returns `true` if this is `Rc<T>`.
2183
2203
pub fn is_rc ( & self ) -> bool {
2184
- self . flags . intersects ( AdtFlags :: IS_RC )
2204
+ self . flags . contains ( AdtFlags :: IS_RC )
2185
2205
}
2186
2206
2187
2207
/// Returns `true` if this is Box<T>.
2188
2208
#[ inline]
2189
2209
pub fn is_box ( & self ) -> bool {
2190
- self . flags . intersects ( AdtFlags :: IS_BOX )
2210
+ self . flags . contains ( AdtFlags :: IS_BOX )
2191
2211
}
2192
2212
2193
2213
/// Returns whether this type has a destructor.
0 commit comments