diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-06-03 17:17:25 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-06-03 17:17:25 +0100 |
commit | 14153671caaca852c94bd1d0d7f279acb8eb1913 (patch) | |
tree | eb377999a5e8677c210791440b18593f909198e6 /crates/hir_def/src/lib.rs | |
parent | 7f9c4a59d9a84cd8c734286937439b5cd215be27 (diff) | |
parent | 17565f4deafab800d8d87208cff1e27d028e9b0e (diff) |
Merge #9128
9128: feat: expand procedural attribute macros r=jonas-schievink a=jonas-schievink
This adds experimental support for attribute macros. They can be enabled by setting `rust-analyzer.experimental.procAttrMacros` to `true`.
Known issues:
* Tokens aren't remapped, presumably because we edit the input syntax tree (this causes IDE features to not work inside items with attribute macros on them)
* Macro errors aren't reported correctly
Closes https://github.com/rust-analyzer/rust-analyzer/issues/8971
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/8964 / https://github.com/la10736/rstest/issues/120
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/2984
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/5412
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/6029
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/6687
https://github.com/rust-analyzer/rust-analyzer/issues/6740 is still not fixed – we now expand `#[proc_macro_hack]`, but fail to expand the resulting `proc_macro_call!()` macro.
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/hir_def/src/lib.rs')
-rw-r--r-- | crates/hir_def/src/lib.rs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 9aa95720a..987485acc 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -55,6 +55,7 @@ use std::{ | |||
55 | sync::Arc, | 55 | sync::Arc, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | use attr::Attr; | ||
58 | use base_db::{impl_intern_key, salsa, CrateId}; | 59 | use base_db::{impl_intern_key, salsa, CrateId}; |
59 | use hir_expand::{ | 60 | use hir_expand::{ |
60 | ast_id_map::FileAstId, | 61 | ast_id_map::FileAstId, |
@@ -768,3 +769,42 @@ fn derive_macro_as_call_id( | |||
768 | .into(); | 769 | .into(); |
769 | Ok(res) | 770 | Ok(res) |
770 | } | 771 | } |
772 | |||
773 | fn attr_macro_as_call_id( | ||
774 | item_attr: &AstIdWithPath<ast::Item>, | ||
775 | macro_attr: &Attr, | ||
776 | db: &dyn db::DefDatabase, | ||
777 | krate: CrateId, | ||
778 | resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, | ||
779 | ) -> Result<MacroCallId, UnresolvedMacro> { | ||
780 | let def: MacroDefId = resolver(item_attr.path.clone()) | ||
781 | .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?; | ||
782 | let last_segment = item_attr | ||
783 | .path | ||
784 | .segments() | ||
785 | .last() | ||
786 | .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?; | ||
787 | let mut arg = match ¯o_attr.input { | ||
788 | Some(input) => match &**input { | ||
789 | attr::AttrInput::Literal(_) => tt::Subtree::default(), | ||
790 | attr::AttrInput::TokenTree(tt) => tt.clone(), | ||
791 | }, | ||
792 | None => tt::Subtree::default(), | ||
793 | }; | ||
794 | // The parentheses are always disposed here. | ||
795 | arg.delimiter = None; | ||
796 | |||
797 | let res = def | ||
798 | .as_lazy_macro( | ||
799 | db.upcast(), | ||
800 | krate, | ||
801 | MacroCallKind::Attr { | ||
802 | ast_id: item_attr.ast_id, | ||
803 | attr_name: last_segment.to_string(), | ||
804 | attr_args: arg, | ||
805 | invoc_attr_index: macro_attr.id.ast_index, | ||
806 | }, | ||
807 | ) | ||
808 | .into(); | ||
809 | Ok(res) | ||
810 | } | ||