Skip to content

Commit 60cd018

Browse files
authored
Merge pull request #19228 from Veykril/push-xxplutrwplou
Split some queries
2 parents 185f9de + 2ea09b2 commit 60cd018

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+836
-783
lines changed

crates/hir-def/src/attr.rs

Lines changed: 126 additions & 1 deletion
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,
@@ -83,7 +84,7 @@ impl Attrs {
8384
let krate = loc.parent.lookup(db).container.krate;
8485
item_tree = loc.id.item_tree(db);
8586
let variant = &item_tree[loc.id.value];
86-
(FieldParent::Variant(loc.id.value), &variant.fields, krate)
87+
(FieldParent::EnumVariant(loc.id.value), &variant.fields, krate)
8788
}
8889
VariantId::StructId(it) => {
8990
let loc = it.lookup(db);
@@ -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)]

0 commit comments

Comments
 (0)