Skip to content

Commit abf21ba

Browse files
author
Paolo Tranquilli
committed
Rust: skip macro expansion in unexpanded attribute macro AST
1 parent 32cece3 commit abf21ba

File tree

3 files changed

+383
-179
lines changed

3 files changed

+383
-179
lines changed

rust/ast-generator/templates/extractor.mustache

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use super::base::Translator;
44
use super::mappings::TextValue;
5-
use crate::emit_detached;
5+
use crate::{pre_emit,post_emit};
66
use crate::generated;
77
use crate::trap::{Label, TrapId};
88
use ra_ap_syntax::ast::{
@@ -22,18 +22,20 @@ impl Translator<'_> {
2222
{{#enums}}
2323

2424
pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option<Label<generated::{{name}}>> {
25+
pre_emit!({{name}}, self, node);
2526
let label = match node {
2627
{{#variants}}
2728
ast::{{ast_name}}::{{variant_ast_name}}(inner) => self.emit_{{snake_case_name}}(inner).map(Into::into),
2829
{{/variants}}
2930
}?;
30-
emit_detached!({{name}}, self, node, label);
31+
post_emit!({{name}}, self, node, label);
3132
Some(label)
3233
}
3334
{{/enums}}
3435
{{#nodes}}
3536

3637
pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option<Label<generated::{{name}}>> {
38+
pre_emit!({{name}}, self, node);
3739
{{#has_attrs}}
3840
if self.should_be_excluded(node) { return None; }
3941
{{/has_attrs}}
@@ -58,7 +60,7 @@ impl Translator<'_> {
5860
{{/fields}}
5961
});
6062
self.emit_location(label, node);
61-
emit_detached!({{name}}, self, node, label);
63+
post_emit!({{name}}, self, node, label);
6264
self.emit_tokens(node, label.into(), node.syntax().children_with_tokens());
6365
Some(label)
6466
}

rust/extractor/src/translate/base.rs

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use ra_ap_hir::{
1111
};
1212
use ra_ap_hir_def::ModuleId;
1313
use ra_ap_hir_def::type_ref::Mutability;
14-
use ra_ap_hir_expand::{ExpandResult, ExpandTo};
14+
use ra_ap_hir_expand::{ExpandResult, ExpandTo, InFile};
1515
use ra_ap_ide_db::RootDatabase;
1616
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
1717
use ra_ap_parser::SyntaxKind;
@@ -23,7 +23,15 @@ use ra_ap_syntax::{
2323
};
2424

2525
#[macro_export]
26-
macro_rules! emit_detached {
26+
macro_rules! pre_emit {
27+
(Item, $self:ident, $node:ident) => {
28+
$self.setup_item_expansion($node);
29+
};
30+
($($_:tt)*) => {};
31+
}
32+
33+
#[macro_export]
34+
macro_rules! post_emit {
2735
(MacroCall, $self:ident, $node:ident, $label:ident) => {
2836
$self.extract_macro_call_expanded($node, $label);
2937
};
@@ -101,7 +109,8 @@ pub struct Translator<'a> {
101109
line_index: LineIndex,
102110
file_id: Option<EditionedFileId>,
103111
pub semantics: Option<&'a Semantics<'a, RootDatabase>>,
104-
resolve_paths: ResolvePaths,
112+
resolve_paths: bool,
113+
macro_context_depth: usize,
105114
}
106115

107116
const UNKNOWN_LOCATION: (LineCol, LineCol) =
@@ -123,7 +132,8 @@ impl<'a> Translator<'a> {
123132
line_index,
124133
file_id: semantic_info.map(|i| i.file_id),
125134
semantics: semantic_info.map(|i| i.semantics),
126-
resolve_paths,
135+
resolve_paths: resolve_paths == ResolvePaths::Yes,
136+
macro_context_depth: 0,
127137
}
128138
}
129139
fn location(&self, range: TextRange) -> Option<(LineCol, LineCol)> {
@@ -321,6 +331,11 @@ impl<'a> Translator<'a> {
321331
mcall: &ast::MacroCall,
322332
label: Label<generated::MacroCall>,
323333
) {
334+
if self.macro_context_depth > 0 {
335+
// we are in an attribute macro, don't emit anything: we would be failing to expand any
336+
// way as rust-analyser now only expands in the context of an expansion
337+
return;
338+
}
324339
if let Some(expanded) = self
325340
.semantics
326341
.as_ref()
@@ -521,7 +536,7 @@ impl<'a> Translator<'a> {
521536
item: &T,
522537
label: Label<generated::Addressable>,
523538
) {
524-
if self.resolve_paths == ResolvePaths::No {
539+
if !self.resolve_paths {
525540
return;
526541
}
527542
(|| {
@@ -544,7 +559,7 @@ impl<'a> Translator<'a> {
544559
item: &ast::Variant,
545560
label: Label<generated::Variant>,
546561
) {
547-
if self.resolve_paths == ResolvePaths::No {
562+
if !self.resolve_paths {
548563
return;
549564
}
550565
(|| {
@@ -567,7 +582,7 @@ impl<'a> Translator<'a> {
567582
item: &impl PathAst,
568583
label: Label<generated::Resolvable>,
569584
) {
570-
if self.resolve_paths == ResolvePaths::No {
585+
if !self.resolve_paths {
571586
return;
572587
}
573588
(|| {
@@ -590,7 +605,7 @@ impl<'a> Translator<'a> {
590605
item: &ast::MethodCallExpr,
591606
label: Label<generated::MethodCallExpr>,
592607
) {
593-
if self.resolve_paths == ResolvePaths::No {
608+
if !self.resolve_paths {
594609
return;
595610
}
596611
(|| {
@@ -653,9 +668,29 @@ impl<'a> Translator<'a> {
653668
}
654669
}
655670

671+
pub(crate) fn setup_item_expansion(&mut self, node: &ast::Item) {
672+
if self.semantics.is_some_and(|s| {
673+
let file = s.hir_file_for(node.syntax());
674+
let node = InFile::new(file, node);
675+
s.is_attr_macro_call(node)
676+
}) {
677+
self.macro_context_depth += 1;
678+
}
679+
}
680+
656681
pub(crate) fn emit_item_expansion(&mut self, node: &ast::Item, label: Label<generated::Item>) {
657682
(|| {
658683
let semantics = self.semantics?;
684+
let file = semantics.hir_file_for(node.syntax());
685+
let infile_node = InFile::new(file, node);
686+
if !semantics.is_attr_macro_call(infile_node) {
687+
return None;
688+
}
689+
self.macro_context_depth -= 1;
690+
if self.macro_context_depth > 0 {
691+
// only expand the outermost attribute macro
692+
return None;
693+
}
659694
let ExpandResult {
660695
value: expanded, ..
661696
} = semantics.expand_attr_macro(node)?;

0 commit comments

Comments
 (0)