Skip to content

Commit dff1896

Browse files
committed
Move attribute parsing out of data module
1 parent 12f54ee commit dff1896

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

226351
#[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,
@@ -73,13 +72,6 @@ impl FunctionData {
7372
}
7473

7574
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
76-
let legacy_const_generics_indices = attrs
77-
.by_key(&sym::rustc_legacy_const_generics)
78-
.tt_values()
79-
.next()
80-
.map(parse_rustc_legacy_const_generics)
81-
.filter(|it| !it.is_empty())
82-
.map(Box::new);
8375
let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists();
8476
if flags.contains(FnFlags::HAS_UNSAFE_KW)
8577
&& attrs.by_key(&sym::rustc_deprecated_safe_2024).exists()
@@ -106,7 +98,7 @@ impl FunctionData {
10698
ret_type: func.ret_type,
10799
visibility,
108100
abi: func.abi.clone(),
109-
legacy_const_generics_indices,
101+
legacy_const_generics_indices: attrs.rustc_legacy_const_generics(),
110102
types_map: func.types_map.clone(),
111103
flags,
112104
rustc_allow_incoherent_impl,
@@ -156,29 +148,6 @@ impl FunctionData {
156148
}
157149
}
158150

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