33use std:: sync:: Arc ;
44
55use base_db:: CrateId ;
6+ use bitflags:: bitflags;
67use cfg:: CfgOptions ;
78use either:: Either ;
89
@@ -20,6 +21,7 @@ use crate::{
2021 builtin_type:: { BuiltinInt , BuiltinUint } ,
2122 db:: DefDatabase ,
2223 item_tree:: { AttrOwner , Field , FieldAstId , Fields , ItemTree , ModItem , RawVisibilityId } ,
24+ lang_item:: LangItem ,
2325 layout:: { Align , ReprFlags , ReprOptions } ,
2426 nameres:: diagnostics:: DefDiagnostic ,
2527 src:: HasChildSource ,
@@ -39,8 +41,26 @@ pub struct StructData {
3941 pub variant_data : Arc < VariantData > ,
4042 pub repr : Option < ReprOptions > ,
4143 pub visibility : RawVisibility ,
42- pub rustc_has_incoherent_inherent_impls : bool ,
43- pub fundamental : bool ,
44+ pub flags : StructFlags ,
45+ }
46+
47+ bitflags ! {
48+ pub struct StructFlags : u8 {
49+ const NO_FLAGS = 0 ;
50+ /// Indicates whether the struct is `PhantomData`.
51+ const IS_PHANTOM_DATA = 1 << 2 ;
52+ /// Indicates whether the struct has a `#[fundamental]` attribute.
53+ const IS_FUNDAMENTAL = 1 << 3 ;
54+ // FIXME: should this be a flag?
55+ /// Indicates whether the struct has a `#[rustc_has_incoherent_inherent_impls]` attribute.
56+ const IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL = 1 << 4 ;
57+ /// Indicates whether this struct is `Box`.
58+ const IS_BOX = 1 << 5 ;
59+ /// Indicates whether this struct is `ManuallyDrop`.
60+ const IS_MANUALLY_DROP = 1 << 6 ;
61+ /// Indicates whether this struct is `UnsafeCell`.
62+ const IS_UNSAFE_CELL = 1 << 6 ;
63+ }
4464}
4565
4666#[ derive( Debug , Clone , PartialEq , Eq ) ]
@@ -174,10 +194,25 @@ impl StructData {
174194 let item_tree = loc. id . item_tree ( db) ;
175195 let repr = repr_from_value ( db, krate, & item_tree, ModItem :: from ( loc. id . value ) . into ( ) ) ;
176196 let cfg_options = db. crate_graph ( ) [ loc. container . krate ] . cfg_options . clone ( ) ;
197+
177198 let attrs = item_tree. attrs ( db, loc. container . krate , ModItem :: from ( loc. id . value ) . into ( ) ) ;
178- let rustc_has_incoherent_inherent_impls =
179- attrs. by_key ( "rustc_has_incoherent_inherent_impls" ) . exists ( ) ;
180- let fundamental = attrs. by_key ( "fundamental" ) . exists ( ) ;
199+
200+ let mut flags = StructFlags :: NO_FLAGS ;
201+ if attrs. by_key ( "rustc_has_incoherent_inherent_impls" ) . exists ( ) {
202+ flags |= StructFlags :: IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL ;
203+ }
204+ if attrs. by_key ( "fundamental" ) . exists ( ) {
205+ flags |= StructFlags :: IS_FUNDAMENTAL ;
206+ }
207+ if let Some ( lang) = attrs. lang_item ( ) {
208+ match lang {
209+ LangItem :: PhantomData => flags |= StructFlags :: IS_PHANTOM_DATA ,
210+ LangItem :: OwnedBox => flags |= StructFlags :: IS_BOX ,
211+ LangItem :: ManuallyDrop => flags |= StructFlags :: IS_MANUALLY_DROP ,
212+ LangItem :: UnsafeCell => flags |= StructFlags :: IS_UNSAFE_CELL ,
213+ _ => ( ) ,
214+ }
215+ }
181216
182217 let strukt = & item_tree[ loc. id . value ] ;
183218 let ( variant_data, diagnostics) = lower_fields (
@@ -196,8 +231,7 @@ impl StructData {
196231 variant_data : Arc :: new ( variant_data) ,
197232 repr,
198233 visibility : item_tree[ strukt. visibility ] . clone ( ) ,
199- rustc_has_incoherent_inherent_impls,
200- fundamental,
234+ flags,
201235 } ) ,
202236 diagnostics. into ( ) ,
203237 )
@@ -218,9 +252,13 @@ impl StructData {
218252 let cfg_options = db. crate_graph ( ) [ loc. container . krate ] . cfg_options . clone ( ) ;
219253
220254 let attrs = item_tree. attrs ( db, loc. container . krate , ModItem :: from ( loc. id . value ) . into ( ) ) ;
221- let rustc_has_incoherent_inherent_impls =
222- attrs. by_key ( "rustc_has_incoherent_inherent_impls" ) . exists ( ) ;
223- let fundamental = attrs. by_key ( "fundamental" ) . exists ( ) ;
255+ let mut flags = StructFlags :: NO_FLAGS ;
256+ if attrs. by_key ( "rustc_has_incoherent_inherent_impls" ) . exists ( ) {
257+ flags |= StructFlags :: IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL ;
258+ }
259+ if attrs. by_key ( "fundamental" ) . exists ( ) {
260+ flags |= StructFlags :: IS_FUNDAMENTAL ;
261+ }
224262
225263 let union = & item_tree[ loc. id . value ] ;
226264 let ( variant_data, diagnostics) = lower_fields (
@@ -239,8 +277,7 @@ impl StructData {
239277 variant_data : Arc :: new ( variant_data) ,
240278 repr,
241279 visibility : item_tree[ union. visibility ] . clone ( ) ,
242- rustc_has_incoherent_inherent_impls,
243- fundamental,
280+ flags,
244281 } ) ,
245282 diagnostics. into ( ) ,
246283 )
0 commit comments