mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Auto merge of #17419 - ishanjain28:filter_builtin_macro_expansion, r=Veykril
Filter builtin macro expansion This PR adds a filter on the types of built in macros that are allowed to be expanded. Currently, This list of allowed macros contains, `stringify, cfg, core_panic, std_panic, concat, concat_bytes, include, include_str, include_bytes, env` and `option_env`. Fixes #14177
This commit is contained in:
commit
6738f81b12
2 changed files with 75 additions and 5 deletions
|
@ -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());
|
||||
|
|
|
@ -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)
|
||||
|
@ -228,6 +229,29 @@ mod tests {
|
|||
expect.assert_eq(&actual);
|
||||
}
|
||||
|
||||
#[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(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue