From ae8d74ab2caed66dc84f64f6859bdf3f131388e1 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 9 Jun 2021 18:02:31 +0200 Subject: Implement dummy expansions for builtin attributes --- crates/hir_expand/src/builtin_attr.rs | 115 ++++++++++++++++++++++++++++++++++ crates/hir_expand/src/db.rs | 14 ++++- crates/hir_expand/src/eager.rs | 1 + crates/hir_expand/src/hygiene.rs | 1 + crates/hir_expand/src/lib.rs | 4 ++ crates/hir_expand/src/name.rs | 9 ++- 6 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 crates/hir_expand/src/builtin_attr.rs (limited to 'crates/hir_expand/src') diff --git a/crates/hir_expand/src/builtin_attr.rs b/crates/hir_expand/src/builtin_attr.rs new file mode 100644 index 000000000..3024410fb --- /dev/null +++ b/crates/hir_expand/src/builtin_attr.rs @@ -0,0 +1,115 @@ +//! Builtin derives. + +use syntax::ast; + +use crate::{db::AstDatabase, name, AstId, CrateId, MacroCallId, MacroDefId, MacroDefKind}; + +macro_rules! register_builtin { + ( $(($name:ident, $variant:ident) => $expand:ident),* ) => { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum BuiltinAttrExpander { + $($variant),* + } + + impl BuiltinAttrExpander { + pub fn expand( + &self, + db: &dyn AstDatabase, + id: MacroCallId, + tt: &tt::Subtree, + ) -> Result { + let expander = match *self { + $( BuiltinAttrExpander::$variant => $expand, )* + }; + expander(db, id, tt) + } + + fn find_by_name(name: &name::Name) -> Option { + match name { + $( id if id == &name::name![$name] => Some(BuiltinAttrExpander::$variant), )* + _ => None, + } + } + } + + }; +} + +register_builtin! { + (bench, Bench) => bench_expand, + (cfg_accessible, CfgAccessible) => cfg_accessible_expand, + (cfg_eval, CfgEval) => cfg_eval_expand, + (derive, Derive) => derive_expand, + (global_allocator, GlobalAllocator) => global_allocator_expand, + (test, Test) => test_expand, + (test_case, TestCase) => test_case_expand +} + +pub fn find_builtin_attr( + ident: &name::Name, + krate: CrateId, + ast_id: AstId, +) -> Option { + let expander = BuiltinAttrExpander::find_by_name(ident)?; + Some(MacroDefId { + krate, + kind: MacroDefKind::BuiltInAttr(expander, ast_id), + local_inner: false, + }) +} + +fn bench_expand( + _db: &dyn AstDatabase, + _id: MacroCallId, + tt: &tt::Subtree, +) -> Result { + Ok(tt.clone()) +} + +fn cfg_accessible_expand( + _db: &dyn AstDatabase, + _id: MacroCallId, + tt: &tt::Subtree, +) -> Result { + Ok(tt.clone()) +} + +fn cfg_eval_expand( + _db: &dyn AstDatabase, + _id: MacroCallId, + tt: &tt::Subtree, +) -> Result { + Ok(tt.clone()) +} + +fn derive_expand( + _db: &dyn AstDatabase, + _id: MacroCallId, + tt: &tt::Subtree, +) -> Result { + Ok(tt.clone()) +} + +fn global_allocator_expand( + _db: &dyn AstDatabase, + _id: MacroCallId, + tt: &tt::Subtree, +) -> Result { + Ok(tt.clone()) +} + +fn test_expand( + _db: &dyn AstDatabase, + _id: MacroCallId, + tt: &tt::Subtree, +) -> Result { + Ok(tt.clone()) +} + +fn test_case_expand( + _db: &dyn AstDatabase, + _id: MacroCallId, + tt: &tt::Subtree, +) -> Result { + Ok(tt.clone()) +} diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index 18a05579f..45e6e446a 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs @@ -12,9 +12,9 @@ use syntax::{ }; use crate::{ - ast_id_map::AstIdMap, hygiene::HygieneFrame, input::process_macro_input, BuiltinDeriveExpander, - BuiltinFnLikeExpander, HirFileId, HirFileIdRepr, MacroCallId, MacroCallKind, MacroCallLoc, - MacroDefId, MacroDefKind, MacroFile, ProcMacroExpander, + ast_id_map::AstIdMap, hygiene::HygieneFrame, input::process_macro_input, BuiltinAttrExpander, + BuiltinDeriveExpander, BuiltinFnLikeExpander, HirFileId, HirFileIdRepr, MacroCallId, + MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind, MacroFile, ProcMacroExpander, }; /// Total limit on the number of tokens produced by any macro invocation. @@ -31,6 +31,8 @@ pub enum TokenExpander { MacroDef { mac: mbe::MacroDef, def_site_token_map: mbe::TokenMap }, /// Stuff like `line!` and `file!`. Builtin(BuiltinFnLikeExpander), + /// `global_allocator` and such. + BuiltinAttr(BuiltinAttrExpander), /// `derive(Copy)` and such. BuiltinDerive(BuiltinDeriveExpander), /// The thing we love the most here in rust-analyzer -- procedural macros. @@ -49,6 +51,7 @@ impl TokenExpander { TokenExpander::MacroDef { mac, .. } => mac.expand(tt), TokenExpander::Builtin(it) => it.expand(db, id, tt), // FIXME switch these to ExpandResult as well + TokenExpander::BuiltinAttr(it) => it.expand(db, id, tt).into(), TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(), TokenExpander::ProcMacro(_) => { // We store the result in salsa db to prevent non-deterministic behavior in @@ -64,6 +67,7 @@ impl TokenExpander { TokenExpander::MacroRules { mac, .. } => mac.map_id_down(id), TokenExpander::MacroDef { mac, .. } => mac.map_id_down(id), TokenExpander::Builtin(..) + | TokenExpander::BuiltinAttr(..) | TokenExpander::BuiltinDerive(..) | TokenExpander::ProcMacro(..) => id, } @@ -74,6 +78,7 @@ impl TokenExpander { TokenExpander::MacroRules { mac, .. } => mac.map_id_up(id), TokenExpander::MacroDef { mac, .. } => mac.map_id_up(id), TokenExpander::Builtin(..) + | TokenExpander::BuiltinAttr(..) | TokenExpander::BuiltinDerive(..) | TokenExpander::ProcMacro(..) => (id, mbe::Origin::Call), } @@ -299,6 +304,9 @@ fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option> } }, MacroDefKind::BuiltIn(expander, _) => Some(Arc::new(TokenExpander::Builtin(expander))), + MacroDefKind::BuiltInAttr(expander, _) => { + Some(Arc::new(TokenExpander::BuiltinAttr(expander))) + } MacroDefKind::BuiltInDerive(expander, _) => { Some(Arc::new(TokenExpander::BuiltinDerive(expander))) } diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs index 14af628a1..9093255f4 100644 --- a/crates/hir_expand/src/eager.rs +++ b/crates/hir_expand/src/eager.rs @@ -224,6 +224,7 @@ fn eager_macro_recur( } MacroDefKind::Declarative(_) | MacroDefKind::BuiltIn(..) + | MacroDefKind::BuiltInAttr(..) | MacroDefKind::BuiltInDerive(..) | MacroDefKind::ProcMacro(..) => { let res = lazy_expand(db, &def, curr.with_value(child.clone()), krate); diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs index d98913907..05c6c3fb1 100644 --- a/crates/hir_expand/src/hygiene.rs +++ b/crates/hir_expand/src/hygiene.rs @@ -192,6 +192,7 @@ impl HygieneFrame { (info, Some(loc.def.krate), loc.def.local_inner) } MacroDefKind::BuiltIn(..) => (info, Some(loc.def.krate), false), + MacroDefKind::BuiltInAttr(..) => (info, None, false), MacroDefKind::BuiltInDerive(..) => (info, None, false), MacroDefKind::BuiltInEager(..) => (info, None, false), MacroDefKind::ProcMacro(..) => (info, None, false), diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index 618f26b95..623791b58 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs @@ -8,6 +8,7 @@ pub mod db; pub mod ast_id_map; pub mod name; pub mod hygiene; +pub mod builtin_attr; pub mod builtin_derive; pub mod builtin_macro; pub mod proc_macro; @@ -32,6 +33,7 @@ use syntax::{ }; use crate::ast_id_map::FileAstId; +use crate::builtin_attr::BuiltinAttrExpander; use crate::builtin_derive::BuiltinDeriveExpander; use crate::builtin_macro::{BuiltinFnLikeExpander, EagerExpander}; use crate::proc_macro::ProcMacroExpander; @@ -206,6 +208,7 @@ impl MacroDefId { let id = match &self.kind { MacroDefKind::Declarative(id) => id, MacroDefKind::BuiltIn(_, id) => id, + MacroDefKind::BuiltInAttr(_, id) => id, MacroDefKind::BuiltInDerive(_, id) => id, MacroDefKind::BuiltInEager(_, id) => id, MacroDefKind::ProcMacro(.., id) => return Either::Right(*id), @@ -223,6 +226,7 @@ pub enum MacroDefKind { Declarative(AstId), BuiltIn(BuiltinFnLikeExpander, AstId), // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander + BuiltInAttr(BuiltinAttrExpander, AstId), BuiltInDerive(BuiltinDeriveExpander, AstId), BuiltInEager(EagerExpander, AstId), ProcMacro(ProcMacroExpander, ProcMacroKind, AstId), diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs index 00b8adc1e..376fe130f 100644 --- a/crates/hir_expand/src/name.rs +++ b/crates/hir_expand/src/name.rs @@ -160,7 +160,6 @@ pub mod known { str, // Special names macro_rules, - derive, doc, cfg, cfg_attr, @@ -240,6 +239,14 @@ pub mod known { PartialOrd, Eq, PartialEq, + // Builtin attributes + bench, + cfg_accessible, + cfg_eval, + derive, + global_allocator, + test, + test_case, // Safe intrinsics abort, size_of, -- cgit v1.2.3