mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Auto merge of #14445 - Veykril:adt-flags, r=Veykril
internal: Introduce StructFlags
This commit is contained in:
commit
02ea92fecb
8 changed files with 93 additions and 58 deletions
|
@ -3,6 +3,7 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use base_db::CrateId;
|
||||
use bitflags::bitflags;
|
||||
use cfg::CfgOptions;
|
||||
use either::Either;
|
||||
|
||||
|
@ -20,6 +21,7 @@ use crate::{
|
|||
builtin_type::{BuiltinInt, BuiltinUint},
|
||||
db::DefDatabase,
|
||||
item_tree::{AttrOwner, Field, FieldAstId, Fields, ItemTree, ModItem, RawVisibilityId},
|
||||
lang_item::LangItem,
|
||||
layout::{Align, ReprFlags, ReprOptions},
|
||||
nameres::diagnostics::DefDiagnostic,
|
||||
src::HasChildSource,
|
||||
|
@ -39,8 +41,26 @@ pub struct StructData {
|
|||
pub variant_data: Arc<VariantData>,
|
||||
pub repr: Option<ReprOptions>,
|
||||
pub visibility: RawVisibility,
|
||||
pub rustc_has_incoherent_inherent_impls: bool,
|
||||
pub fundamental: bool,
|
||||
pub flags: StructFlags,
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct StructFlags: u8 {
|
||||
const NO_FLAGS = 0;
|
||||
/// Indicates whether the struct is `PhantomData`.
|
||||
const IS_PHANTOM_DATA = 1 << 2;
|
||||
/// Indicates whether the struct has a `#[fundamental]` attribute.
|
||||
const IS_FUNDAMENTAL = 1 << 3;
|
||||
// FIXME: should this be a flag?
|
||||
/// Indicates whether the struct has a `#[rustc_has_incoherent_inherent_impls]` attribute.
|
||||
const IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL = 1 << 4;
|
||||
/// Indicates whether this struct is `Box`.
|
||||
const IS_BOX = 1 << 5;
|
||||
/// Indicates whether this struct is `ManuallyDrop`.
|
||||
const IS_MANUALLY_DROP = 1 << 6;
|
||||
/// Indicates whether this struct is `UnsafeCell`.
|
||||
const IS_UNSAFE_CELL = 1 << 6;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
@ -174,10 +194,25 @@ impl StructData {
|
|||
let item_tree = loc.id.item_tree(db);
|
||||
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
|
||||
let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
|
||||
|
||||
let attrs = item_tree.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into());
|
||||
let rustc_has_incoherent_inherent_impls =
|
||||
attrs.by_key("rustc_has_incoherent_inherent_impls").exists();
|
||||
let fundamental = attrs.by_key("fundamental").exists();
|
||||
|
||||
let mut flags = StructFlags::NO_FLAGS;
|
||||
if attrs.by_key("rustc_has_incoherent_inherent_impls").exists() {
|
||||
flags |= StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL;
|
||||
}
|
||||
if attrs.by_key("fundamental").exists() {
|
||||
flags |= StructFlags::IS_FUNDAMENTAL;
|
||||
}
|
||||
if let Some(lang) = attrs.lang_item() {
|
||||
match lang {
|
||||
LangItem::PhantomData => flags |= StructFlags::IS_PHANTOM_DATA,
|
||||
LangItem::OwnedBox => flags |= StructFlags::IS_BOX,
|
||||
LangItem::ManuallyDrop => flags |= StructFlags::IS_MANUALLY_DROP,
|
||||
LangItem::UnsafeCell => flags |= StructFlags::IS_UNSAFE_CELL,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
let strukt = &item_tree[loc.id.value];
|
||||
let (variant_data, diagnostics) = lower_fields(
|
||||
|
@ -196,8 +231,7 @@ impl StructData {
|
|||
variant_data: Arc::new(variant_data),
|
||||
repr,
|
||||
visibility: item_tree[strukt.visibility].clone(),
|
||||
rustc_has_incoherent_inherent_impls,
|
||||
fundamental,
|
||||
flags,
|
||||
}),
|
||||
diagnostics.into(),
|
||||
)
|
||||
|
@ -218,9 +252,13 @@ impl StructData {
|
|||
let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
|
||||
|
||||
let attrs = item_tree.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into());
|
||||
let rustc_has_incoherent_inherent_impls =
|
||||
attrs.by_key("rustc_has_incoherent_inherent_impls").exists();
|
||||
let fundamental = attrs.by_key("fundamental").exists();
|
||||
let mut flags = StructFlags::NO_FLAGS;
|
||||
if attrs.by_key("rustc_has_incoherent_inherent_impls").exists() {
|
||||
flags |= StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL;
|
||||
}
|
||||
if attrs.by_key("fundamental").exists() {
|
||||
flags |= StructFlags::IS_FUNDAMENTAL;
|
||||
}
|
||||
|
||||
let union = &item_tree[loc.id.value];
|
||||
let (variant_data, diagnostics) = lower_fields(
|
||||
|
@ -239,8 +277,7 @@ impl StructData {
|
|||
variant_data: Arc::new(variant_data),
|
||||
repr,
|
||||
visibility: item_tree[union.visibility].clone(),
|
||||
rustc_has_incoherent_inherent_impls,
|
||||
fundamental,
|
||||
flags,
|
||||
}),
|
||||
diagnostics.into(),
|
||||
)
|
||||
|
|
|
@ -20,6 +20,7 @@ use syntax::{
|
|||
use crate::{
|
||||
db::DefDatabase,
|
||||
item_tree::{AttrOwner, Fields, ItemTreeId, ItemTreeNode},
|
||||
lang_item::LangItem,
|
||||
nameres::{ModuleOrigin, ModuleSource},
|
||||
src::{HasChildSource, HasSource},
|
||||
AdtId, AttrDefId, EnumId, GenericParamId, LocalEnumVariantId, LocalFieldId, Lookup, MacroId,
|
||||
|
@ -177,13 +178,13 @@ impl Attrs {
|
|||
|
||||
Arc::new(res)
|
||||
}
|
||||
|
||||
pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
|
||||
AttrQuery { attrs: self, key }
|
||||
}
|
||||
}
|
||||
|
||||
impl Attrs {
|
||||
pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
|
||||
AttrQuery { attrs: self, key }
|
||||
}
|
||||
|
||||
pub fn cfg(&self) -> Option<CfgExpr> {
|
||||
let mut cfgs = self.by_key("cfg").tt_values().map(CfgExpr::parse);
|
||||
let first = cfgs.next()?;
|
||||
|
@ -206,6 +207,10 @@ impl Attrs {
|
|||
self.by_key("lang").string_value()
|
||||
}
|
||||
|
||||
pub fn lang_item(&self) -> Option<LangItem> {
|
||||
self.by_key("lang").string_value().and_then(|it| LangItem::from_str(it))
|
||||
}
|
||||
|
||||
pub fn docs(&self) -> Option<Documentation> {
|
||||
let docs = self.by_key("doc").attrs().filter_map(|attr| attr.string_value());
|
||||
let indent = doc_indent(self);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue