mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Move attribute parsing out of data module
This commit is contained in:
parent
12f54eec27
commit
dff1896436
@ -12,6 +12,7 @@ use hir_expand::{
|
|||||||
use intern::{sym, Symbol};
|
use intern::{sym, Symbol};
|
||||||
use la_arena::{ArenaMap, Idx, RawIdx};
|
use la_arena::{ArenaMap, Idx, RawIdx};
|
||||||
use mbe::DelimiterKind;
|
use mbe::DelimiterKind;
|
||||||
|
use rustc_abi::ReprOptions;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, HasAttrs},
|
ast::{self, HasAttrs},
|
||||||
AstPtr,
|
AstPtr,
|
||||||
@ -221,6 +222,130 @@ impl Attrs {
|
|||||||
pub fn is_unstable(&self) -> bool {
|
pub fn is_unstable(&self) -> bool {
|
||||||
self.by_key(&sym::unstable).exists()
|
self.by_key(&sym::unstable).exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rustc_legacy_const_generics(&self) -> Option<Box<Box<[u32]>>> {
|
||||||
|
self.by_key(&sym::rustc_legacy_const_generics)
|
||||||
|
.tt_values()
|
||||||
|
.next()
|
||||||
|
.map(parse_rustc_legacy_const_generics)
|
||||||
|
.filter(|it| !it.is_empty())
|
||||||
|
.map(Box::new)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn repr(&self) -> Option<ReprOptions> {
|
||||||
|
self.by_key(&sym::repr).tt_values().find_map(parse_repr_tt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_rustc_legacy_const_generics(tt: &crate::tt::TopSubtree) -> Box<[u32]> {
|
||||||
|
let mut indices = Vec::new();
|
||||||
|
let mut iter = tt.iter();
|
||||||
|
while let (Some(first), second) = (iter.next(), iter.next()) {
|
||||||
|
match first {
|
||||||
|
TtElement::Leaf(tt::Leaf::Literal(lit)) => match lit.symbol.as_str().parse() {
|
||||||
|
Ok(index) => indices.push(index),
|
||||||
|
Err(_) => break,
|
||||||
|
},
|
||||||
|
_ => break,
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(comma) = second {
|
||||||
|
match comma {
|
||||||
|
TtElement::Leaf(tt::Leaf::Punct(punct)) if punct.char == ',' => {}
|
||||||
|
_ => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
indices.into_boxed_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_repr_tt(tt: &crate::tt::TopSubtree) -> Option<ReprOptions> {
|
||||||
|
use crate::builtin_type::{BuiltinInt, BuiltinUint};
|
||||||
|
use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions};
|
||||||
|
|
||||||
|
match tt.top_subtree().delimiter {
|
||||||
|
tt::Delimiter { kind: DelimiterKind::Parenthesis, .. } => {}
|
||||||
|
_ => return None,
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut flags = ReprFlags::empty();
|
||||||
|
let mut int = None;
|
||||||
|
let mut max_align: Option<Align> = None;
|
||||||
|
let mut min_pack: Option<Align> = None;
|
||||||
|
|
||||||
|
let mut tts = tt.iter();
|
||||||
|
while let Some(tt) = tts.next() {
|
||||||
|
if let TtElement::Leaf(tt::Leaf::Ident(ident)) = tt {
|
||||||
|
flags.insert(match &ident.sym {
|
||||||
|
s if *s == sym::packed => {
|
||||||
|
let pack = if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() {
|
||||||
|
tts.next();
|
||||||
|
if let Some(TtElement::Leaf(tt::Leaf::Literal(lit))) = tt_iter.next() {
|
||||||
|
lit.symbol.as_str().parse().unwrap_or_default()
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
let pack = Align::from_bytes(pack).unwrap_or(Align::ONE);
|
||||||
|
min_pack =
|
||||||
|
Some(if let Some(min_pack) = min_pack { min_pack.min(pack) } else { pack });
|
||||||
|
ReprFlags::empty()
|
||||||
|
}
|
||||||
|
s if *s == sym::align => {
|
||||||
|
if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() {
|
||||||
|
tts.next();
|
||||||
|
if let Some(TtElement::Leaf(tt::Leaf::Literal(lit))) = tt_iter.next() {
|
||||||
|
if let Ok(align) = lit.symbol.as_str().parse() {
|
||||||
|
let align = Align::from_bytes(align).ok();
|
||||||
|
max_align = max_align.max(align);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReprFlags::empty()
|
||||||
|
}
|
||||||
|
s if *s == sym::C => ReprFlags::IS_C,
|
||||||
|
s if *s == sym::transparent => ReprFlags::IS_TRANSPARENT,
|
||||||
|
s if *s == sym::simd => ReprFlags::IS_SIMD,
|
||||||
|
repr => {
|
||||||
|
if let Some(builtin) = BuiltinInt::from_suffix_sym(repr)
|
||||||
|
.map(Either::Left)
|
||||||
|
.or_else(|| BuiltinUint::from_suffix_sym(repr).map(Either::Right))
|
||||||
|
{
|
||||||
|
int = Some(match builtin {
|
||||||
|
Either::Left(bi) => match bi {
|
||||||
|
BuiltinInt::Isize => IntegerType::Pointer(true),
|
||||||
|
BuiltinInt::I8 => IntegerType::Fixed(Integer::I8, true),
|
||||||
|
BuiltinInt::I16 => IntegerType::Fixed(Integer::I16, true),
|
||||||
|
BuiltinInt::I32 => IntegerType::Fixed(Integer::I32, true),
|
||||||
|
BuiltinInt::I64 => IntegerType::Fixed(Integer::I64, true),
|
||||||
|
BuiltinInt::I128 => IntegerType::Fixed(Integer::I128, true),
|
||||||
|
},
|
||||||
|
Either::Right(bu) => match bu {
|
||||||
|
BuiltinUint::Usize => IntegerType::Pointer(false),
|
||||||
|
BuiltinUint::U8 => IntegerType::Fixed(Integer::I8, false),
|
||||||
|
BuiltinUint::U16 => IntegerType::Fixed(Integer::I16, false),
|
||||||
|
BuiltinUint::U32 => IntegerType::Fixed(Integer::I32, false),
|
||||||
|
BuiltinUint::U64 => IntegerType::Fixed(Integer::I64, false),
|
||||||
|
BuiltinUint::U128 => IntegerType::Fixed(Integer::I128, false),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ReprFlags::empty()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(ReprOptions {
|
||||||
|
int,
|
||||||
|
align: max_align,
|
||||||
|
pack: min_pack,
|
||||||
|
flags,
|
||||||
|
field_shuffle_seed: rustc_hashes::Hash64::ZERO,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -7,7 +7,6 @@ use hir_expand::name::Name;
|
|||||||
use intern::{sym, Symbol};
|
use intern::{sym, Symbol};
|
||||||
use la_arena::{Idx, RawIdx};
|
use la_arena::{Idx, RawIdx};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
use tt::iter::TtElement;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
@ -73,13 +72,6 @@ impl FunctionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
|
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
|
||||||
let legacy_const_generics_indices = attrs
|
|
||||||
.by_key(&sym::rustc_legacy_const_generics)
|
|
||||||
.tt_values()
|
|
||||||
.next()
|
|
||||||
.map(parse_rustc_legacy_const_generics)
|
|
||||||
.filter(|it| !it.is_empty())
|
|
||||||
.map(Box::new);
|
|
||||||
let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists();
|
let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists();
|
||||||
if flags.contains(FnFlags::HAS_UNSAFE_KW)
|
if flags.contains(FnFlags::HAS_UNSAFE_KW)
|
||||||
&& attrs.by_key(&sym::rustc_deprecated_safe_2024).exists()
|
&& attrs.by_key(&sym::rustc_deprecated_safe_2024).exists()
|
||||||
@ -106,7 +98,7 @@ impl FunctionData {
|
|||||||
ret_type: func.ret_type,
|
ret_type: func.ret_type,
|
||||||
visibility,
|
visibility,
|
||||||
abi: func.abi.clone(),
|
abi: func.abi.clone(),
|
||||||
legacy_const_generics_indices,
|
legacy_const_generics_indices: attrs.rustc_legacy_const_generics(),
|
||||||
types_map: func.types_map.clone(),
|
types_map: func.types_map.clone(),
|
||||||
flags,
|
flags,
|
||||||
rustc_allow_incoherent_impl,
|
rustc_allow_incoherent_impl,
|
||||||
@ -156,29 +148,6 @@ impl FunctionData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_rustc_legacy_const_generics(tt: &crate::tt::TopSubtree) -> Box<[u32]> {
|
|
||||||
let mut indices = Vec::new();
|
|
||||||
let mut iter = tt.iter();
|
|
||||||
while let (Some(first), second) = (iter.next(), iter.next()) {
|
|
||||||
match first {
|
|
||||||
TtElement::Leaf(tt::Leaf::Literal(lit)) => match lit.symbol.as_str().parse() {
|
|
||||||
Ok(index) => indices.push(index),
|
|
||||||
Err(_) => break,
|
|
||||||
},
|
|
||||||
_ => break,
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(comma) = second {
|
|
||||||
match comma {
|
|
||||||
TtElement::Leaf(tt::Leaf::Punct(punct)) if punct.char == ',' => {}
|
|
||||||
_ => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
indices.into_boxed_slice()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct TypeAliasData {
|
pub struct TypeAliasData {
|
||||||
pub name: Name,
|
pub name: Name,
|
||||||
|
@ -3,18 +3,14 @@
|
|||||||
use base_db::Crate;
|
use base_db::Crate;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use cfg::CfgOptions;
|
use cfg::CfgOptions;
|
||||||
use either::Either;
|
|
||||||
|
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
use intern::sym;
|
use intern::sym;
|
||||||
use la_arena::Arena;
|
use la_arena::Arena;
|
||||||
use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions};
|
use rustc_abi::{IntegerType, ReprOptions};
|
||||||
use rustc_hashes::Hash64;
|
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
use tt::iter::TtElement;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
builtin_type::{BuiltinInt, BuiltinUint},
|
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
hir::Expr,
|
hir::Expr,
|
||||||
item_tree::{
|
item_tree::{
|
||||||
@ -22,7 +18,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
lang_item::LangItem,
|
lang_item::LangItem,
|
||||||
nameres::diagnostics::{DefDiagnostic, DefDiagnostics},
|
nameres::diagnostics::{DefDiagnostic, DefDiagnostics},
|
||||||
tt::{Delimiter, DelimiterKind, Leaf, TopSubtree},
|
|
||||||
type_ref::{TypeRefId, TypesMap},
|
type_ref::{TypeRefId, TypesMap},
|
||||||
visibility::RawVisibility,
|
visibility::RawVisibility,
|
||||||
EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId, VariantId,
|
EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId, VariantId,
|
||||||
@ -94,92 +89,7 @@ fn repr_from_value(
|
|||||||
item_tree: &ItemTree,
|
item_tree: &ItemTree,
|
||||||
of: AttrOwner,
|
of: AttrOwner,
|
||||||
) -> Option<ReprOptions> {
|
) -> Option<ReprOptions> {
|
||||||
item_tree.attrs(db, krate, of).by_key(&sym::repr).tt_values().find_map(parse_repr_tt)
|
item_tree.attrs(db, krate, of).repr()
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_repr_tt(tt: &TopSubtree) -> Option<ReprOptions> {
|
|
||||||
match tt.top_subtree().delimiter {
|
|
||||||
Delimiter { kind: DelimiterKind::Parenthesis, .. } => {}
|
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut flags = ReprFlags::empty();
|
|
||||||
let mut int = None;
|
|
||||||
let mut max_align: Option<Align> = None;
|
|
||||||
let mut min_pack: Option<Align> = None;
|
|
||||||
|
|
||||||
let mut tts = tt.iter();
|
|
||||||
while let Some(tt) = tts.next() {
|
|
||||||
if let TtElement::Leaf(Leaf::Ident(ident)) = tt {
|
|
||||||
flags.insert(match &ident.sym {
|
|
||||||
s if *s == sym::packed => {
|
|
||||||
let pack = if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() {
|
|
||||||
tts.next();
|
|
||||||
if let Some(TtElement::Leaf(Leaf::Literal(lit))) = tt_iter.next() {
|
|
||||||
lit.symbol.as_str().parse().unwrap_or_default()
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
let pack = Align::from_bytes(pack).unwrap_or(Align::ONE);
|
|
||||||
min_pack =
|
|
||||||
Some(if let Some(min_pack) = min_pack { min_pack.min(pack) } else { pack });
|
|
||||||
ReprFlags::empty()
|
|
||||||
}
|
|
||||||
s if *s == sym::align => {
|
|
||||||
if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() {
|
|
||||||
tts.next();
|
|
||||||
if let Some(TtElement::Leaf(Leaf::Literal(lit))) = tt_iter.next() {
|
|
||||||
if let Ok(align) = lit.symbol.as_str().parse() {
|
|
||||||
let align = Align::from_bytes(align).ok();
|
|
||||||
max_align = max_align.max(align);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ReprFlags::empty()
|
|
||||||
}
|
|
||||||
s if *s == sym::C => ReprFlags::IS_C,
|
|
||||||
s if *s == sym::transparent => ReprFlags::IS_TRANSPARENT,
|
|
||||||
s if *s == sym::simd => ReprFlags::IS_SIMD,
|
|
||||||
repr => {
|
|
||||||
if let Some(builtin) = BuiltinInt::from_suffix_sym(repr)
|
|
||||||
.map(Either::Left)
|
|
||||||
.or_else(|| BuiltinUint::from_suffix_sym(repr).map(Either::Right))
|
|
||||||
{
|
|
||||||
int = Some(match builtin {
|
|
||||||
Either::Left(bi) => match bi {
|
|
||||||
BuiltinInt::Isize => IntegerType::Pointer(true),
|
|
||||||
BuiltinInt::I8 => IntegerType::Fixed(Integer::I8, true),
|
|
||||||
BuiltinInt::I16 => IntegerType::Fixed(Integer::I16, true),
|
|
||||||
BuiltinInt::I32 => IntegerType::Fixed(Integer::I32, true),
|
|
||||||
BuiltinInt::I64 => IntegerType::Fixed(Integer::I64, true),
|
|
||||||
BuiltinInt::I128 => IntegerType::Fixed(Integer::I128, true),
|
|
||||||
},
|
|
||||||
Either::Right(bu) => match bu {
|
|
||||||
BuiltinUint::Usize => IntegerType::Pointer(false),
|
|
||||||
BuiltinUint::U8 => IntegerType::Fixed(Integer::I8, false),
|
|
||||||
BuiltinUint::U16 => IntegerType::Fixed(Integer::I16, false),
|
|
||||||
BuiltinUint::U32 => IntegerType::Fixed(Integer::I32, false),
|
|
||||||
BuiltinUint::U64 => IntegerType::Fixed(Integer::I64, false),
|
|
||||||
BuiltinUint::U128 => IntegerType::Fixed(Integer::I128, false),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ReprFlags::empty()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(ReprOptions {
|
|
||||||
int,
|
|
||||||
align: max_align,
|
|
||||||
pack: min_pack,
|
|
||||||
flags,
|
|
||||||
field_shuffle_seed: Hash64::ZERO,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StructData {
|
impl StructData {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user