Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir/src/semantics.rs50
-rw-r--r--crates/ide/src/expand_macro.rs30
2 files changed, 75 insertions, 5 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 2a5112abd8..2618ea3dec 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -19,8 +19,12 @@ use hir_def::{
AsMacroCall, DefWithBodyId, FunctionId, MacroId, TraitId, VariantId,
};
use hir_expand::{
- attrs::collect_attrs, db::ExpandDatabase, files::InRealFile, name::AsName, InMacroFile,
- MacroCallId, MacroFileId, MacroFileIdExt,
+ attrs::collect_attrs,
+ builtin_fn_macro::{BuiltinFnLikeExpander, EagerExpander},
+ db::ExpandDatabase,
+ files::InRealFile,
+ name::AsName,
+ InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt,
};
use itertools::Itertools;
use rustc_hash::{FxHashMap, FxHashSet};
@@ -324,6 +328,48 @@ impl<'db> SemanticsImpl<'db> {
Some(node)
}
+ /// Expands the macro if it isn't one of the built-in ones that expand to custom syntax or dummy
+ /// expansions.
+ pub fn expand_allowed_builtins(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
+ let sa = self.analyze_no_infer(macro_call.syntax())?;
+
+ let macro_call = InFile::new(sa.file_id, macro_call);
+ let file_id = if let Some(call) =
+ <ast::MacroCall as crate::semantics::ToDef>::to_def(self, macro_call)
+ {
+ call.as_macro_file()
+ } else {
+ sa.expand(self.db, macro_call)?
+ };
+ let macro_call = self.db.lookup_intern_macro_call(file_id.macro_call_id);
+
+ let skip = matches!(
+ macro_call.def.kind,
+ hir_expand::MacroDefKind::BuiltIn(
+ _,
+ BuiltinFnLikeExpander::Column
+ | BuiltinFnLikeExpander::File
+ | BuiltinFnLikeExpander::ModulePath
+ | BuiltinFnLikeExpander::Asm
+ | BuiltinFnLikeExpander::LlvmAsm
+ | BuiltinFnLikeExpander::GlobalAsm
+ | BuiltinFnLikeExpander::LogSyntax
+ | BuiltinFnLikeExpander::TraceMacros
+ | BuiltinFnLikeExpander::FormatArgs
+ | BuiltinFnLikeExpander::FormatArgsNl
+ | BuiltinFnLikeExpander::ConstFormatArgs,
+ ) | hir_expand::MacroDefKind::BuiltInEager(_, EagerExpander::CompileError)
+ );
+ if skip {
+ // these macros expand to custom builtin syntax and/or dummy things, no point in
+ // showing these to the user
+ return None;
+ }
+
+ let node = self.parse_or_expand(file_id.into());
+ Some(node)
+ }
+
/// If `item` has an attribute macro attached to it, expands it.
pub fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> {
let src = self.wrap_node_infile(item.clone());
diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs
index 1ead045788..4b54c057bf 100644
--- a/crates/ide/src/expand_macro.rs
+++ b/crates/ide/src/expand_macro.rs
@@ -111,9 +111,10 @@ fn expand_macro_recur(
macro_call: &ast::Item,
) -> Option<SyntaxNode> {
let expanded = match macro_call {
- item @ ast::Item::MacroCall(macro_call) => {
- sema.expand_attr_macro(item).or_else(|| sema.expand(macro_call))?.clone_for_update()
- }
+ item @ ast::Item::MacroCall(macro_call) => sema
+ .expand_attr_macro(item)
+ .or_else(|| sema.expand_allowed_builtins(macro_call))?
+ .clone_for_update(),
item => sema.expand_attr_macro(item)?.clone_for_update(),
};
expand(sema, expanded)
@@ -229,6 +230,29 @@ mod tests {
}
#[test]
+ fn expand_allowed_builtin_macro() {
+ check(
+ r#"
+//- minicore: concat
+$0concat!("test", 10, 'b', true);"#,
+ expect![[r#"
+ concat!
+ "test10btrue""#]],
+ );
+ }
+
+ #[test]
+ fn do_not_expand_disallowed_macro() {
+ let (analysis, pos) = fixture::position(
+ r#"
+//- minicore: asm
+$0asm!("0x300, x0");"#,
+ );
+ let expansion = analysis.expand_macro(pos).unwrap();
+ assert!(expansion.is_none());
+ }
+
+ #[test]
fn macro_expand_as_keyword() {
check(
r#"