about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2025-02-26 07:55:00 +0100
committerLukas Wirth <lukastw97@gmail.com>2025-03-14 13:31:41 +0100
commit1835bc2a874b6f55af759dbf7361370a65294b62 (patch)
tree00596c1f5d1e48cfee40b9dbe0ce1cc781ec6085 /src
parent9ccee20d423f567220ce8f29ee215f5d1a17736b (diff)
downloadrust-1835bc2a874b6f55af759dbf7361370a65294b62.tar.gz
rust-1835bc2a874b6f55af759dbf7361370a65294b62.zip
Move attribute parsing out of data module
Diffstat (limited to 'src')
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/attr.rs125
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/data.rs33
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs94
3 files changed, 128 insertions, 124 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
index 579ea12e6ae..030d064584c 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
@@ -12,6 +12,7 @@ use hir_expand::{
 use intern::{sym, Symbol};
 use la_arena::{ArenaMap, Idx, RawIdx};
 use mbe::DelimiterKind;
+use rustc_abi::ReprOptions;
 use syntax::{
     ast::{self, HasAttrs},
     AstPtr,
@@ -221,6 +222,130 @@ impl Attrs {
     pub fn is_unstable(&self) -> bool {
         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)]
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
index 8a1f07c92ef..1a6bed6cabb 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
@@ -7,7 +7,6 @@ use hir_expand::name::Name;
 use intern::{sym, Symbol};
 use la_arena::{Idx, RawIdx};
 use triomphe::Arc;
-use tt::iter::TtElement;
 
 use crate::{
     db::DefDatabase,
@@ -73,13 +72,6 @@ impl FunctionData {
         }
 
         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();
         if flags.contains(FnFlags::HAS_UNSAFE_KW)
             && attrs.by_key(&sym::rustc_deprecated_safe_2024).exists()
@@ -106,7 +98,7 @@ impl FunctionData {
             ret_type: func.ret_type,
             visibility,
             abi: func.abi.clone(),
-            legacy_const_generics_indices,
+            legacy_const_generics_indices: attrs.rustc_legacy_const_generics(),
             types_map: func.types_map.clone(),
             flags,
             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)]
 pub struct TypeAliasData {
     pub name: Name,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs
index bf8f5024c2d..161b205c809 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs
@@ -3,18 +3,14 @@
 use base_db::Crate;
 use bitflags::bitflags;
 use cfg::CfgOptions;
-use either::Either;
 
 use hir_expand::name::Name;
 use intern::sym;
 use la_arena::Arena;
-use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions};
-use rustc_hashes::Hash64;
+use rustc_abi::{IntegerType, ReprOptions};
 use triomphe::Arc;
-use tt::iter::TtElement;
 
 use crate::{
-    builtin_type::{BuiltinInt, BuiltinUint},
     db::DefDatabase,
     hir::Expr,
     item_tree::{
@@ -22,7 +18,6 @@ use crate::{
     },
     lang_item::LangItem,
     nameres::diagnostics::{DefDiagnostic, DefDiagnostics},
-    tt::{Delimiter, DelimiterKind, Leaf, TopSubtree},
     type_ref::{TypeRefId, TypesMap},
     visibility::RawVisibility,
     EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId, VariantId,
@@ -94,92 +89,7 @@ fn repr_from_value(
     item_tree: &ItemTree,
     of: AttrOwner,
 ) -> Option<ReprOptions> {
-    item_tree.attrs(db, krate, of).by_key(&sym::repr).tt_values().find_map(parse_repr_tt)
-}
-
-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,
-    })
+    item_tree.attrs(db, krate, of).repr()
 }
 
 impl StructData {