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,
|
AsMacroCall, DefWithBodyId, FunctionId, MacroId, TraitId, VariantId,
|
||||||
};
|
};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
attrs::collect_attrs, db::ExpandDatabase, files::InRealFile, name::AsName, InMacroFile,
|
attrs::collect_attrs,
|
||||||
MacroCallId, MacroFileId, MacroFileIdExt,
|
builtin_fn_macro::{BuiltinFnLikeExpander, EagerExpander},
|
||||||
|
db::ExpandDatabase,
|
||||||
|
files::InRealFile,
|
||||||
|
name::AsName,
|
||||||
|
InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
@ -324,6 +328,48 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
Some(node)
|
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.
|
/// If `item` has an attribute macro attached to it, expands it.
|
||||||
pub fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> {
|
pub fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> {
|
||||||
let src = self.wrap_node_infile(item.clone());
|
let src = self.wrap_node_infile(item.clone());
|
||||||
|
|
|
@ -111,9 +111,10 @@ fn expand_macro_recur(
|
||||||
macro_call: &ast::Item,
|
macro_call: &ast::Item,
|
||||||
) -> Option<SyntaxNode> {
|
) -> Option<SyntaxNode> {
|
||||||
let expanded = match macro_call {
|
let expanded = match macro_call {
|
||||||
item @ ast::Item::MacroCall(macro_call) => {
|
item @ ast::Item::MacroCall(macro_call) => sema
|
||||||
sema.expand_attr_macro(item).or_else(|| sema.expand(macro_call))?.clone_for_update()
|
.expand_attr_macro(item)
|
||||||
}
|
.or_else(|| sema.expand_allowed_builtins(macro_call))?
|
||||||
|
.clone_for_update(),
|
||||||
item => sema.expand_attr_macro(item)?.clone_for_update(),
|
item => sema.expand_attr_macro(item)?.clone_for_update(),
|
||||||
};
|
};
|
||||||
expand(sema, expanded)
|
expand(sema, expanded)
|
||||||
|
@ -228,6 +229,29 @@ mod tests {
|
||||||
expect.assert_eq(&actual);
|
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]
|
#[test]
|
||||||
fn macro_expand_as_keyword() {
|
fn macro_expand_as_keyword() {
|
||||||
check(
|
check(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue