Skip to content

Commit d303a2c

Browse files
authored
Merge branch 'main' into redsun82/cargo-upgrade-3
2 parents 089f353 + 666144e commit d303a2c

File tree

3 files changed

+212
-49
lines changed

3 files changed

+212
-49
lines changed

rust/extractor/src/translate/base.rs

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,17 @@ use ra_ap_syntax::{
2626
macro_rules! pre_emit {
2727
(Item, $self:ident, $node:ident) => {
2828
if let Some(label) = $self.prepare_item_expansion($node) {
29-
return Some(label);
29+
return Some(label.into());
30+
}
31+
};
32+
(AssocItem, $self:ident, $node:ident) => {
33+
if let Some(label) = $self.prepare_item_expansion(&$node.clone().into()) {
34+
return Some(label.into());
35+
}
36+
};
37+
(ExternItem, $self:ident, $node:ident) => {
38+
if let Some(label) = $self.prepare_item_expansion(&$node.clone().into()) {
39+
return Some(label.into());
3040
}
3141
};
3242
(Meta, $self:ident, $node:ident) => {
@@ -36,6 +46,22 @@ macro_rules! pre_emit {
3646
($($_:tt)*) => {};
3747
}
3848

49+
// TODO: remove the mannually written Label conversions. These can be auto-generated by
50+
// changing the base class of AssocItem from AstNode to Item
51+
impl From<crate::trap::Label<generated::AssocItem>> for crate::trap::Label<generated::Item> {
52+
fn from(value: crate::trap::Label<generated::AssocItem>) -> Self {
53+
// SAFETY: this is safe because every concrete instance of `@assoc_item` is also an instance of `@item`
54+
unsafe { Self::from_untyped(value.as_untyped()) }
55+
}
56+
}
57+
// TODO: remove the mannually written Label conversions. These can be auto-generated by
58+
// changing the base class of ExternItem from AstNode to Item
59+
impl From<crate::trap::Label<generated::ExternItem>> for crate::trap::Label<generated::Item> {
60+
fn from(value: crate::trap::Label<generated::ExternItem>) -> Self {
61+
// SAFETY: this is safe because every concrete instance of `@extern_item` is also an instance of `@item`
62+
unsafe { Self::from_untyped(value.as_untyped()) }
63+
}
64+
}
3965
#[macro_export]
4066
macro_rules! post_emit {
4167
(MacroCall, $self:ident, $node:ident, $label:ident) => {
@@ -66,6 +92,18 @@ macro_rules! post_emit {
6692
(Item, $self:ident, $node:ident, $label:ident) => {
6793
$self.emit_item_expansion($node, $label);
6894
};
95+
(AssocItem, $self:ident, $node:ident, $label:ident) => {
96+
$self.emit_item_expansion(
97+
&$node.clone().into(),
98+
From::<Label<generated::AssocItem>>::from($label),
99+
);
100+
};
101+
(ExternItem, $self:ident, $node:ident, $label:ident) => {
102+
$self.emit_item_expansion(
103+
&$node.clone().into(),
104+
From::<Label<generated::ExternItem>>::from($label),
105+
);
106+
};
69107
// TODO canonical origin of other items
70108
(PathExpr, $self:ident, $node:ident, $label:ident) => {
71109
$self.extract_path_canonical_destination($node, $label.into());
@@ -737,10 +775,21 @@ impl<'a> Translator<'a> {
737775
}
738776
}
739777

778+
fn is_attribute_macro_target(&self, node: &ast::Item) -> bool {
779+
// rust-analyzer considers as an `attr_macro_call` also a plain macro call, but we want to
780+
// process that differently (in `extract_macro_call_expanded`)
781+
!matches!(node, ast::Item::MacroCall(_))
782+
&& self.semantics.is_some_and(|semantics| {
783+
let file = semantics.hir_file_for(node.syntax());
784+
let node = InFile::new(file, node);
785+
semantics.is_attr_macro_call(node)
786+
})
787+
}
788+
740789
pub(crate) fn prepare_item_expansion(
741790
&mut self,
742791
node: &ast::Item,
743-
) -> Option<Label<generated::Item>> {
792+
) -> Option<Label<generated::MacroCall>> {
744793
if self.source_kind == SourceKind::Library {
745794
// if the item expands via an attribute macro, we want to only emit the expansion
746795
if let Some(expanded) = self.emit_attribute_macro_expansion(node) {
@@ -757,13 +806,10 @@ impl<'a> Translator<'a> {
757806
expanded.into(),
758807
&mut self.trap.writer,
759808
);
760-
return Some(label.into());
809+
return Some(label);
761810
}
762811
}
763-
let semantics = self.semantics.as_ref()?;
764-
let file = semantics.hir_file_for(node.syntax());
765-
let node = InFile::new(file, node);
766-
if semantics.is_attr_macro_call(node) {
812+
if self.is_attribute_macro_target(node) {
767813
self.macro_context_depth += 1;
768814
}
769815
None
@@ -773,10 +819,7 @@ impl<'a> Translator<'a> {
773819
&mut self,
774820
node: &ast::Item,
775821
) -> Option<Label<generated::MacroItems>> {
776-
let semantics = self.semantics?;
777-
let file = semantics.hir_file_for(node.syntax());
778-
let infile_node = InFile::new(file, node);
779-
if !semantics.is_attr_macro_call(infile_node) {
822+
if !self.is_attribute_macro_target(node) {
780823
return None;
781824
}
782825
self.macro_context_depth -= 1;

rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected

Lines changed: 145 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,151 @@ macro_expansion.rs:
406406
# 30| getItem(6): [Impl] impl S { ... }
407407
# 30| getAssocItemList(): [AssocItemList] AssocItemList
408408
# 31| getAssocItem(0): [Function] fn bzz
409+
# 32| getAttributeMacroExpansion(): [MacroItems] MacroItems
410+
# 32| getItem(0): [Function] fn bzz_0
411+
# 32| getParamList(): [ParamList] ParamList
412+
# 32| getBody(): [BlockExpr] { ... }
413+
# 32| getStmtList(): [StmtList] StmtList
414+
# 33| getStatement(0): [ExprStmt] ExprStmt
415+
# 33| getExpr(): [MacroExpr] MacroExpr
416+
# 33| getMacroCall(): [MacroCall] hello!...
417+
# 33| getPath(): [Path] hello
418+
# 33| getSegment(): [PathSegment] hello
419+
# 33| getIdentifier(): [NameRef] hello
420+
# 33| getTokenTree(): [TokenTree] TokenTree
421+
# 31| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
422+
# 31| getStatement(0): [ExprStmt] ExprStmt
423+
# 31| getExpr(): [MacroExpr] MacroExpr
424+
# 31| getMacroCall(): [MacroCall] println!...
425+
# 31| getPath(): [Path] println
426+
# 31| getSegment(): [PathSegment] println
427+
# 31| getIdentifier(): [NameRef] println
428+
# 31| getTokenTree(): [TokenTree] TokenTree
429+
# 31| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
430+
# 31| getTailExpr(): [BlockExpr] { ... }
431+
# 31| getStmtList(): [StmtList] StmtList
432+
# 31| getStatement(0): [ExprStmt] ExprStmt
433+
# 31| getExpr(): [CallExpr] ...::_print(...)
434+
# 31| getArgList(): [ArgList] ArgList
435+
# 31| getArg(0): [MacroExpr] MacroExpr
436+
# 31| getMacroCall(): [MacroCall] ...::format_args_nl!...
437+
# 31| getPath(): [Path] ...::format_args_nl
438+
# 31| getQualifier(): [Path] $crate
439+
# 31| getSegment(): [PathSegment] $crate
440+
# 31| getIdentifier(): [NameRef] $crate
441+
# 31| getSegment(): [PathSegment] format_args_nl
442+
# 31| getIdentifier(): [NameRef] format_args_nl
443+
# 31| getTokenTree(): [TokenTree] TokenTree
444+
# 31| getMacroCallExpansion(): [FormatArgsExpr] FormatArgsExpr
445+
# 31| getTemplate(): [StringLiteralExpr] "hello!\n"
446+
# 31| getFunction(): [PathExpr] ...::_print
447+
# 31| getPath(): [Path] ...::_print
448+
# 31| getQualifier(): [Path] ...::io
449+
# 31| getQualifier(): [Path] $crate
450+
# 31| getSegment(): [PathSegment] $crate
451+
# 31| getIdentifier(): [NameRef] $crate
452+
# 31| getSegment(): [PathSegment] io
453+
# 31| getIdentifier(): [NameRef] io
454+
# 31| getSegment(): [PathSegment] _print
455+
# 31| getIdentifier(): [NameRef] _print
456+
# 32| getName(): [Name] bzz_0
457+
# 32| getVisibility(): [Visibility] Visibility
458+
# 32| getItem(1): [Function] fn bzz_1
459+
# 32| getParamList(): [ParamList] ParamList
460+
# 32| getBody(): [BlockExpr] { ... }
461+
# 32| getStmtList(): [StmtList] StmtList
462+
# 33| getStatement(0): [ExprStmt] ExprStmt
463+
# 33| getExpr(): [MacroExpr] MacroExpr
464+
# 33| getMacroCall(): [MacroCall] hello!...
465+
# 33| getPath(): [Path] hello
466+
# 33| getSegment(): [PathSegment] hello
467+
# 33| getIdentifier(): [NameRef] hello
468+
# 33| getTokenTree(): [TokenTree] TokenTree
469+
# 31| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
470+
# 31| getStatement(0): [ExprStmt] ExprStmt
471+
# 31| getExpr(): [MacroExpr] MacroExpr
472+
# 31| getMacroCall(): [MacroCall] println!...
473+
# 31| getPath(): [Path] println
474+
# 31| getSegment(): [PathSegment] println
475+
# 31| getIdentifier(): [NameRef] println
476+
# 31| getTokenTree(): [TokenTree] TokenTree
477+
# 31| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
478+
# 31| getTailExpr(): [BlockExpr] { ... }
479+
# 31| getStmtList(): [StmtList] StmtList
480+
# 31| getStatement(0): [ExprStmt] ExprStmt
481+
# 31| getExpr(): [CallExpr] ...::_print(...)
482+
# 31| getArgList(): [ArgList] ArgList
483+
# 31| getArg(0): [MacroExpr] MacroExpr
484+
# 31| getMacroCall(): [MacroCall] ...::format_args_nl!...
485+
# 31| getPath(): [Path] ...::format_args_nl
486+
# 31| getQualifier(): [Path] $crate
487+
# 31| getSegment(): [PathSegment] $crate
488+
# 31| getIdentifier(): [NameRef] $crate
489+
# 31| getSegment(): [PathSegment] format_args_nl
490+
# 31| getIdentifier(): [NameRef] format_args_nl
491+
# 31| getTokenTree(): [TokenTree] TokenTree
492+
# 31| getMacroCallExpansion(): [FormatArgsExpr] FormatArgsExpr
493+
# 31| getTemplate(): [StringLiteralExpr] "hello!\n"
494+
# 31| getFunction(): [PathExpr] ...::_print
495+
# 31| getPath(): [Path] ...::_print
496+
# 31| getQualifier(): [Path] ...::io
497+
# 31| getQualifier(): [Path] $crate
498+
# 31| getSegment(): [PathSegment] $crate
499+
# 31| getIdentifier(): [NameRef] $crate
500+
# 31| getSegment(): [PathSegment] io
501+
# 31| getIdentifier(): [NameRef] io
502+
# 31| getSegment(): [PathSegment] _print
503+
# 31| getIdentifier(): [NameRef] _print
504+
# 32| getName(): [Name] bzz_1
505+
# 32| getVisibility(): [Visibility] Visibility
506+
# 32| getItem(2): [Function] fn bzz_2
507+
# 32| getParamList(): [ParamList] ParamList
508+
# 32| getBody(): [BlockExpr] { ... }
509+
# 32| getStmtList(): [StmtList] StmtList
510+
# 33| getStatement(0): [ExprStmt] ExprStmt
511+
# 33| getExpr(): [MacroExpr] MacroExpr
512+
# 33| getMacroCall(): [MacroCall] hello!...
513+
# 33| getPath(): [Path] hello
514+
# 33| getSegment(): [PathSegment] hello
515+
# 33| getIdentifier(): [NameRef] hello
516+
# 33| getTokenTree(): [TokenTree] TokenTree
517+
# 31| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
518+
# 31| getStatement(0): [ExprStmt] ExprStmt
519+
# 31| getExpr(): [MacroExpr] MacroExpr
520+
# 31| getMacroCall(): [MacroCall] println!...
521+
# 31| getPath(): [Path] println
522+
# 31| getSegment(): [PathSegment] println
523+
# 31| getIdentifier(): [NameRef] println
524+
# 31| getTokenTree(): [TokenTree] TokenTree
525+
# 31| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
526+
# 31| getTailExpr(): [BlockExpr] { ... }
527+
# 31| getStmtList(): [StmtList] StmtList
528+
# 31| getStatement(0): [ExprStmt] ExprStmt
529+
# 31| getExpr(): [CallExpr] ...::_print(...)
530+
# 31| getArgList(): [ArgList] ArgList
531+
# 31| getArg(0): [MacroExpr] MacroExpr
532+
# 31| getMacroCall(): [MacroCall] ...::format_args_nl!...
533+
# 31| getPath(): [Path] ...::format_args_nl
534+
# 31| getQualifier(): [Path] $crate
535+
# 31| getSegment(): [PathSegment] $crate
536+
# 31| getIdentifier(): [NameRef] $crate
537+
# 31| getSegment(): [PathSegment] format_args_nl
538+
# 31| getIdentifier(): [NameRef] format_args_nl
539+
# 31| getTokenTree(): [TokenTree] TokenTree
540+
# 31| getMacroCallExpansion(): [FormatArgsExpr] FormatArgsExpr
541+
# 31| getTemplate(): [StringLiteralExpr] "hello!\n"
542+
# 31| getFunction(): [PathExpr] ...::_print
543+
# 31| getPath(): [Path] ...::_print
544+
# 31| getQualifier(): [Path] ...::io
545+
# 31| getQualifier(): [Path] $crate
546+
# 31| getSegment(): [PathSegment] $crate
547+
# 31| getIdentifier(): [NameRef] $crate
548+
# 31| getSegment(): [PathSegment] io
549+
# 31| getIdentifier(): [NameRef] io
550+
# 31| getSegment(): [PathSegment] _print
551+
# 31| getIdentifier(): [NameRef] _print
552+
# 32| getName(): [Name] bzz_2
553+
# 32| getVisibility(): [Visibility] Visibility
409554
# 32| getParamList(): [ParamList] ParamList
410555
# 31| getAttr(0): [Attr] Attr
411556
# 31| getMeta(): [Meta] Meta
@@ -422,41 +567,6 @@ macro_expansion.rs:
422567
# 33| getSegment(): [PathSegment] hello
423568
# 33| getIdentifier(): [NameRef] hello
424569
# 33| getTokenTree(): [TokenTree] TokenTree
425-
# 33| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
426-
# 33| getStatement(0): [ExprStmt] ExprStmt
427-
# 33| getExpr(): [MacroExpr] MacroExpr
428-
# 33| getMacroCall(): [MacroCall] println!...
429-
# 33| getPath(): [Path] println
430-
# 33| getSegment(): [PathSegment] println
431-
# 33| getIdentifier(): [NameRef] println
432-
# 33| getTokenTree(): [TokenTree] TokenTree
433-
# 33| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
434-
# 33| getTailExpr(): [BlockExpr] { ... }
435-
# 33| getStmtList(): [StmtList] StmtList
436-
# 33| getStatement(0): [ExprStmt] ExprStmt
437-
# 33| getExpr(): [CallExpr] ...::_print(...)
438-
# 33| getArgList(): [ArgList] ArgList
439-
# 33| getArg(0): [MacroExpr] MacroExpr
440-
# 33| getMacroCall(): [MacroCall] ...::format_args_nl!...
441-
# 33| getPath(): [Path] ...::format_args_nl
442-
# 33| getQualifier(): [Path] $crate
443-
# 33| getSegment(): [PathSegment] $crate
444-
# 33| getIdentifier(): [NameRef] $crate
445-
# 33| getSegment(): [PathSegment] format_args_nl
446-
# 33| getIdentifier(): [NameRef] format_args_nl
447-
# 33| getTokenTree(): [TokenTree] TokenTree
448-
# 33| getMacroCallExpansion(): [FormatArgsExpr] FormatArgsExpr
449-
# 33| getTemplate(): [StringLiteralExpr] "hello!\n"
450-
# 33| getFunction(): [PathExpr] ...::_print
451-
# 33| getPath(): [Path] ...::_print
452-
# 33| getQualifier(): [Path] ...::io
453-
# 33| getQualifier(): [Path] $crate
454-
# 33| getSegment(): [PathSegment] $crate
455-
# 33| getIdentifier(): [NameRef] $crate
456-
# 33| getSegment(): [PathSegment] io
457-
# 33| getIdentifier(): [NameRef] io
458-
# 33| getSegment(): [PathSegment] _print
459-
# 33| getIdentifier(): [NameRef] _print
460570
# 32| getName(): [Name] bzz
461571
# 32| getVisibility(): [Visibility] Visibility
462572
# 30| getSelfTy(): [PathTypeRepr] S

0 commit comments

Comments
 (0)