Skip to content

Commit b2816be

Browse files
committed
Move attribute parsing out of data module
1 parent 2e52fc1 commit b2816be

File tree

3 files changed

+128
-124
lines changed

3 files changed

+128
-124
lines changed

crates/hir-def/src/attr.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use hir_expand::{
1212
use intern::{sym, Symbol};
1313
use la_arena::{ArenaMap, Idx, RawIdx};
1414
use mbe::DelimiterKind;
15+
use rustc_abi::ReprOptions;
1516
use syntax::{
1617
ast::{self, HasAttrs},
1718
AstPtr,
@@ -222,6 +223,130 @@ impl Attrs {
222223
pub fn is_unstable(&self) -> bool {
223224
self.by_key(&sym::unstable).exists()
224225
}
226+
227+
pub fn rustc_legacy_const_generics(&self) -> Option<Box<Box<[u32]>>> {
228+
self.by_key(&sym::rustc_legacy_const_generics)
229+
.tt_values()
230+
.next()
231+
.map(parse_rustc_legacy_const_generics)
232+
.filter(|it| !it.is_empty())
233+
.map(Box::new)
234+
}
235+
236+
pub fn repr(&self) -> Option<ReprOptions> {
237+
self.by_key(&sym::repr).tt_values().find_map(parse_repr_tt)
238+
}
239+
}
240+
241+
fn parse_rustc_legacy_const_generics(tt: &crate::tt::TopSubtree) -> Box<[u32]> {
242+
let mut indices = Vec::new();
243+
let mut iter = tt.iter();
244+
while let (Some(first), second) = (iter.next(), iter.next()) {
245+
match first {
246+
TtElement::Leaf(tt::Leaf::Literal(lit)) => match lit.symbol.as_str().parse() {
247+
Ok(index) => indices.push(index),
248+
Err(_) => break,
249+
},
250+
_ => break,
251+
}
252+
253+
if let Some(comma) = second {
254+
match comma {
255+
TtElement::Leaf(tt::Leaf::Punct(punct)) if punct.char == ',' => {}
256+
_ => break,
257+
}
258+
}
259+
}
260+
261+
indices.into_boxed_slice()
262+
}
263+
264+
fn parse_repr_tt(tt: &crate::tt::TopSubtree) -> Option<ReprOptions> {
265+
use crate::builtin_type::{BuiltinInt, BuiltinUint};
266+
use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions};
267+
268+
match tt.top_subtree().delimiter {
269+
tt::Delimiter { kind: DelimiterKind::Parenthesis, .. } => {}
270+
_ => return None,
271+
}
272+
273+
let mut flags = ReprFlags::empty();
274+
let mut int = None;
275+
let mut max_align: Option<Align> = None;
276+
let mut min_pack: Option<Align> = None;
277+
278+
let mut tts = tt.iter();
279+
while let Some(tt) = tts.next() {
280+
if let TtElement::Leaf(tt::Leaf::Ident(ident)) = tt {
281+
flags.insert(match &ident.sym {
282+
s if *s == sym::packed => {
283+
let pack = if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() {
284+
tts.next();
285+
if let Some(TtElement::Leaf(tt::Leaf::Literal(lit))) = tt_iter.next() {
286+
lit.symbol.as_str().parse().unwrap_or_default()
287+
} else {
288+
0
289+
}
290+
} else {
291+
0
292+
};
293+
let pack = Align::from_bytes(pack).unwrap_or(Align::ONE);
294+
min_pack =
295+
Some(if let Some(min_pack) = min_pack { min_pack.min(pack) } else { pack });
296+
ReprFlags::empty()
297+
}
298+
s if *s == sym::align => {
299+
if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() {
300+
tts.next();
301+
if let Some(TtElement::Leaf(tt::Leaf::Literal(lit))) = tt_iter.next() {
302+
if let Ok(align) = lit.symbol.as_str().parse() {
303+
let align = Align::from_bytes(align).ok();
304+
max_align = max_align.max(align);
305+
}
306+
}
307+
}
308+
ReprFlags::empty()
309+
}
310+
s if *s == sym::C => ReprFlags::IS_C,
311+
s if *s == sym::transparent => ReprFlags::IS_TRANSPARENT,
312+
s if *s == sym::simd => ReprFlags::IS_SIMD,
313+
repr => {
314+
if let Some(builtin) = BuiltinInt::from_suffix_sym(repr)
315+
.map(Either::Left)
316+
.or_else(|| BuiltinUint::from_suffix_sym(repr).map(Either::Right))
317+
{
318+
int = Some(match builtin {
319+
Either::Left(bi) => match bi {
320+
BuiltinInt::Isize => IntegerType::Pointer(true),
321+
BuiltinInt::I8 => IntegerType::Fixed(Integer::I8, true),
322+
BuiltinInt::I16 => IntegerType::Fixed(Integer::I16, true),
323+
BuiltinInt::I32 => IntegerType::Fixed(Integer::I32, true),
324+
BuiltinInt::I64 => IntegerType::Fixed(Integer::I64, true),
325+
BuiltinInt::I128 => IntegerType::Fixed(Integer::I128, true),
326+
},
327+
Either::Right(bu) => match bu {
328+
BuiltinUint::Usize => IntegerType::Pointer(false),
329+
BuiltinUint::U8 => IntegerType::Fixed(Integer::I8, false),
330+
BuiltinUint::U16 => IntegerType::Fixed(Integer::I16, false),
331+
BuiltinUint::U32 => IntegerType::Fixed(Integer::I32, false),
332+
BuiltinUint::U64 => IntegerType::Fixed(Integer::I64, false),
333+
BuiltinUint::U128 => IntegerType::Fixed(Integer::I128, false),
334+
},
335+
});
336+
}
337+
ReprFlags::empty()
338+
}
339+
})
340+
}
341+
}
342+
343+
Some(ReprOptions {
344+
int,
345+
align: max_align,
346+
pack: min_pack,
347+
flags,
348+
field_shuffle_seed: rustc_hashes::Hash64::ZERO,
349+
})
225350
}
226351

227352
#[derive(Debug, Clone, PartialEq, Eq, Hash)]

crates/hir-def/src/data.rs

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use hir_expand::name::Name;
77
use intern::{sym, Symbol};
88
use la_arena::{Idx, RawIdx};
99
use triomphe::Arc;
10-
use tt::iter::TtElement;
1110

1211
use crate::{
1312
db::DefDatabase,
@@ -74,13 +73,6 @@ impl FunctionData {
7473
}
7574

7675
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
77-
let legacy_const_generics_indices = attrs
78-
.by_key(&sym::rustc_legacy_const_generics)
79-
.tt_values()
80-
.next()
81-
.map(parse_rustc_legacy_const_generics)
82-
.filter(|it| !it.is_empty())
83-
.map(Box::new);
8476
let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists();
8577
if flags.contains(FnFlags::HAS_UNSAFE_KW)
8678
&& attrs.by_key(&sym::rustc_deprecated_safe_2024).exists()
@@ -107,7 +99,7 @@ impl FunctionData {
10799
ret_type: func.ret_type,
108100
visibility,
109101
abi: func.abi.clone(),
110-
legacy_const_generics_indices,
102+
legacy_const_generics_indices: attrs.rustc_legacy_const_generics(),
111103
types_map: func.types_map.clone(),
112104
flags,
113105
rustc_allow_incoherent_impl,
@@ -157,29 +149,6 @@ impl FunctionData {
157149
}
158150
}
159151

160-
fn parse_rustc_legacy_const_generics(tt: &crate::tt::TopSubtree) -> Box<[u32]> {
161-
let mut indices = Vec::new();
162-
let mut iter = tt.iter();
163-
while let (Some(first), second) = (iter.next(), iter.next()) {
164-
match first {
165-
TtElement::Leaf(tt::Leaf::Literal(lit)) => match lit.symbol.as_str().parse() {
166-
Ok(index) => indices.push(index),
167-
Err(_) => break,
168-
},
169-
_ => break,
170-
}
171-
172-
if let Some(comma) = second {
173-
match comma {
174-
TtElement::Leaf(tt::Leaf::Punct(punct)) if punct.char == ',' => {}
175-
_ => break,
176-
}
177-
}
178-
}
179-
180-
indices.into_boxed_slice()
181-
}
182-
183152
#[derive(Debug, Clone, PartialEq, Eq)]
184153
pub struct TypeAliasData {
185154
pub name: Name,

crates/hir-def/src/data/adt.rs

Lines changed: 2 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,21 @@
33
use base_db::CrateId;
44
use bitflags::bitflags;
55
use cfg::CfgOptions;
6-
use either::Either;
76

87
use hir_expand::name::Name;
98
use intern::sym;
109
use la_arena::Arena;
11-
use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions};
12-
use rustc_hashes::Hash64;
10+
use rustc_abi::{IntegerType, ReprOptions};
1311
use triomphe::Arc;
14-
use tt::iter::TtElement;
1512

1613
use crate::{
17-
builtin_type::{BuiltinInt, BuiltinUint},
1814
db::DefDatabase,
1915
hir::Expr,
2016
item_tree::{
2117
AttrOwner, Field, FieldParent, FieldsShape, ItemTree, ModItem, RawVisibilityId, TreeId,
2218
},
2319
lang_item::LangItem,
2420
nameres::diagnostics::{DefDiagnostic, DefDiagnostics},
25-
tt::{Delimiter, DelimiterKind, Leaf, TopSubtree},
2621
type_ref::{TypeRefId, TypesMap},
2722
visibility::RawVisibility,
2823
EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId, VariantId,
@@ -94,92 +89,7 @@ fn repr_from_value(
9489
item_tree: &ItemTree,
9590
of: AttrOwner,
9691
) -> Option<ReprOptions> {
97-
item_tree.attrs(db, krate, of).by_key(&sym::repr).tt_values().find_map(parse_repr_tt)
98-
}
99-
100-
fn parse_repr_tt(tt: &TopSubtree) -> Option<ReprOptions> {
101-
match tt.top_subtree().delimiter {
102-
Delimiter { kind: DelimiterKind::Parenthesis, .. } => {}
103-
_ => return None,
104-
}
105-
106-
let mut flags = ReprFlags::empty();
107-
let mut int = None;
108-
let mut max_align: Option<Align> = None;
109-
let mut min_pack: Option<Align> = None;
110-
111-
let mut tts = tt.iter();
112-
while let Some(tt) = tts.next() {
113-
if let TtElement::Leaf(Leaf::Ident(ident)) = tt {
114-
flags.insert(match &ident.sym {
115-
s if *s == sym::packed => {
116-
let pack = if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() {
117-
tts.next();
118-
if let Some(TtElement::Leaf(Leaf::Literal(lit))) = tt_iter.next() {
119-
lit.symbol.as_str().parse().unwrap_or_default()
120-
} else {
121-
0
122-
}
123-
} else {
124-
0
125-
};
126-
let pack = Align::from_bytes(pack).unwrap_or(Align::ONE);
127-
min_pack =
128-
Some(if let Some(min_pack) = min_pack { min_pack.min(pack) } else { pack });
129-
ReprFlags::empty()
130-
}
131-
s if *s == sym::align => {
132-
if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() {
133-
tts.next();
134-
if let Some(TtElement::Leaf(Leaf::Literal(lit))) = tt_iter.next() {
135-
if let Ok(align) = lit.symbol.as_str().parse() {
136-
let align = Align::from_bytes(align).ok();
137-
max_align = max_align.max(align);
138-
}
139-
}
140-
}
141-
ReprFlags::empty()
142-
}
143-
s if *s == sym::C => ReprFlags::IS_C,
144-
s if *s == sym::transparent => ReprFlags::IS_TRANSPARENT,
145-
s if *s == sym::simd => ReprFlags::IS_SIMD,
146-
repr => {
147-
if let Some(builtin) = BuiltinInt::from_suffix_sym(repr)
148-
.map(Either::Left)
149-
.or_else(|| BuiltinUint::from_suffix_sym(repr).map(Either::Right))
150-
{
151-
int = Some(match builtin {
152-
Either::Left(bi) => match bi {
153-
BuiltinInt::Isize => IntegerType::Pointer(true),
154-
BuiltinInt::I8 => IntegerType::Fixed(Integer::I8, true),
155-
BuiltinInt::I16 => IntegerType::Fixed(Integer::I16, true),
156-
BuiltinInt::I32 => IntegerType::Fixed(Integer::I32, true),
157-
BuiltinInt::I64 => IntegerType::Fixed(Integer::I64, true),
158-
BuiltinInt::I128 => IntegerType::Fixed(Integer::I128, true),
159-
},
160-
Either::Right(bu) => match bu {
161-
BuiltinUint::Usize => IntegerType::Pointer(false),
162-
BuiltinUint::U8 => IntegerType::Fixed(Integer::I8, false),
163-
BuiltinUint::U16 => IntegerType::Fixed(Integer::I16, false),
164-
BuiltinUint::U32 => IntegerType::Fixed(Integer::I32, false),
165-
BuiltinUint::U64 => IntegerType::Fixed(Integer::I64, false),
166-
BuiltinUint::U128 => IntegerType::Fixed(Integer::I128, false),
167-
},
168-
});
169-
}
170-
ReprFlags::empty()
171-
}
172-
})
173-
}
174-
}
175-
176-
Some(ReprOptions {
177-
int,
178-
align: max_align,
179-
pack: min_pack,
180-
flags,
181-
field_shuffle_seed: Hash64::ZERO,
182-
})
92+
item_tree.attrs(db, krate, of).repr()
18393
}
18494

18595
impl StructData {

0 commit comments

Comments
 (0)