From 32cece3a43a72447a4c927eded79ba4875c10fdf Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 16 May 2025 16:14:51 +0200 Subject: [PATCH 1/7] Rust: adapt `BadCtorInitialization.ql` to attribute macro expansion --- .../security/CWE-696/BadCtorInitialization.ql | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index 80364a9de06a..75946d89e11b 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -44,9 +44,18 @@ class PathElement = AstNode; * reachable from a source. */ predicate edgesFwd(PathElement pred, PathElement succ) { - // attribute (source) -> callable - pred.(CtorAttr) = succ.(Callable).getAnAttr() + // attribute (source) -> function in macro expansion + exists(Function f | + pred.(CtorAttr) = f.getAnAttr() and + ( + f.getAttributeMacroExpansion().getAnItem() = succ.(Callable) + or + // if for some reason the ctor/dtor macro expansion failed, fall back to looking into the unexpanded item + not f.hasAttributeMacroExpansion() and f = succ.(Callable) + ) + ) or + // callable -> callable attribute macro expansion // [forwards reachable] callable -> enclosed call edgesFwd(_, pred) and pred = succ.(CallExprBase).getEnclosingCallable() From abf21ba767e2a23c7ddeda6df33c36549f307da1 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 16 May 2025 16:15:03 +0200 Subject: [PATCH 2/7] Rust: skip macro expansion in unexpanded attribute macro AST --- .../templates/extractor.mustache | 8 +- rust/extractor/src/translate/base.rs | 51 +- rust/extractor/src/translate/generated.rs | 503 ++++++++++++------ 3 files changed, 383 insertions(+), 179 deletions(-) diff --git a/rust/ast-generator/templates/extractor.mustache b/rust/ast-generator/templates/extractor.mustache index c4f8dbd983df..d0c11bb78e08 100644 --- a/rust/ast-generator/templates/extractor.mustache +++ b/rust/ast-generator/templates/extractor.mustache @@ -2,7 +2,7 @@ use super::base::Translator; use super::mappings::TextValue; -use crate::emit_detached; +use crate::{pre_emit,post_emit}; use crate::generated; use crate::trap::{Label, TrapId}; use ra_ap_syntax::ast::{ @@ -22,18 +22,20 @@ impl Translator<'_> { {{#enums}} pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option> { + pre_emit!({{name}}, self, node); let label = match node { {{#variants}} ast::{{ast_name}}::{{variant_ast_name}}(inner) => self.emit_{{snake_case_name}}(inner).map(Into::into), {{/variants}} }?; - emit_detached!({{name}}, self, node, label); + post_emit!({{name}}, self, node, label); Some(label) } {{/enums}} {{#nodes}} pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option> { + pre_emit!({{name}}, self, node); {{#has_attrs}} if self.should_be_excluded(node) { return None; } {{/has_attrs}} @@ -58,7 +60,7 @@ impl Translator<'_> { {{/fields}} }); self.emit_location(label, node); - emit_detached!({{name}}, self, node, label); + post_emit!({{name}}, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } diff --git a/rust/extractor/src/translate/base.rs b/rust/extractor/src/translate/base.rs index d0e99e8a5b45..d1cec34242c9 100644 --- a/rust/extractor/src/translate/base.rs +++ b/rust/extractor/src/translate/base.rs @@ -11,7 +11,7 @@ use ra_ap_hir::{ }; use ra_ap_hir_def::ModuleId; use ra_ap_hir_def::type_ref::Mutability; -use ra_ap_hir_expand::{ExpandResult, ExpandTo}; +use ra_ap_hir_expand::{ExpandResult, ExpandTo, InFile}; use ra_ap_ide_db::RootDatabase; use ra_ap_ide_db::line_index::{LineCol, LineIndex}; use ra_ap_parser::SyntaxKind; @@ -23,7 +23,15 @@ use ra_ap_syntax::{ }; #[macro_export] -macro_rules! emit_detached { +macro_rules! pre_emit { + (Item, $self:ident, $node:ident) => { + $self.setup_item_expansion($node); + }; + ($($_:tt)*) => {}; +} + +#[macro_export] +macro_rules! post_emit { (MacroCall, $self:ident, $node:ident, $label:ident) => { $self.extract_macro_call_expanded($node, $label); }; @@ -101,7 +109,8 @@ pub struct Translator<'a> { line_index: LineIndex, file_id: Option, pub semantics: Option<&'a Semantics<'a, RootDatabase>>, - resolve_paths: ResolvePaths, + resolve_paths: bool, + macro_context_depth: usize, } const UNKNOWN_LOCATION: (LineCol, LineCol) = @@ -123,7 +132,8 @@ impl<'a> Translator<'a> { line_index, file_id: semantic_info.map(|i| i.file_id), semantics: semantic_info.map(|i| i.semantics), - resolve_paths, + resolve_paths: resolve_paths == ResolvePaths::Yes, + macro_context_depth: 0, } } fn location(&self, range: TextRange) -> Option<(LineCol, LineCol)> { @@ -321,6 +331,11 @@ impl<'a> Translator<'a> { mcall: &ast::MacroCall, label: Label, ) { + if self.macro_context_depth > 0 { + // we are in an attribute macro, don't emit anything: we would be failing to expand any + // way as rust-analyser now only expands in the context of an expansion + return; + } if let Some(expanded) = self .semantics .as_ref() @@ -521,7 +536,7 @@ impl<'a> Translator<'a> { item: &T, label: Label, ) { - if self.resolve_paths == ResolvePaths::No { + if !self.resolve_paths { return; } (|| { @@ -544,7 +559,7 @@ impl<'a> Translator<'a> { item: &ast::Variant, label: Label, ) { - if self.resolve_paths == ResolvePaths::No { + if !self.resolve_paths { return; } (|| { @@ -567,7 +582,7 @@ impl<'a> Translator<'a> { item: &impl PathAst, label: Label, ) { - if self.resolve_paths == ResolvePaths::No { + if !self.resolve_paths { return; } (|| { @@ -590,7 +605,7 @@ impl<'a> Translator<'a> { item: &ast::MethodCallExpr, label: Label, ) { - if self.resolve_paths == ResolvePaths::No { + if !self.resolve_paths { return; } (|| { @@ -653,9 +668,29 @@ impl<'a> Translator<'a> { } } + pub(crate) fn setup_item_expansion(&mut self, node: &ast::Item) { + if self.semantics.is_some_and(|s| { + let file = s.hir_file_for(node.syntax()); + let node = InFile::new(file, node); + s.is_attr_macro_call(node) + }) { + self.macro_context_depth += 1; + } + } + pub(crate) fn emit_item_expansion(&mut self, node: &ast::Item, label: Label) { (|| { let semantics = self.semantics?; + let file = semantics.hir_file_for(node.syntax()); + let infile_node = InFile::new(file, node); + if !semantics.is_attr_macro_call(infile_node) { + return None; + } + self.macro_context_depth -= 1; + if self.macro_context_depth > 0 { + // only expand the outermost attribute macro + return None; + } let ExpandResult { value: expanded, .. } = semantics.expand_attr_macro(node)?; diff --git a/rust/extractor/src/translate/generated.rs b/rust/extractor/src/translate/generated.rs index 5002f09c4d86..fe8da75770c8 100644 --- a/rust/extractor/src/translate/generated.rs +++ b/rust/extractor/src/translate/generated.rs @@ -1,9 +1,9 @@ //! Generated by `ast-generator`, do not edit by hand. use super::base::Translator; use super::mappings::TextValue; -use crate::emit_detached; use crate::generated; use crate::trap::{Label, TrapId}; +use crate::{post_emit, pre_emit}; use ra_ap_syntax::ast::{ HasArgList, HasAttrs, HasGenericArgs, HasGenericParams, HasLoopBody, HasModuleItem, HasName, HasTypeBounds, HasVisibility, RangeItem, @@ -21,6 +21,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmOperand, ) -> Option> { + pre_emit!(AsmOperand, self, node); let label = match node { ast::AsmOperand::AsmConst(inner) => self.emit_asm_const(inner).map(Into::into), ast::AsmOperand::AsmLabel(inner) => self.emit_asm_label(inner).map(Into::into), @@ -29,13 +30,14 @@ impl Translator<'_> { } ast::AsmOperand::AsmSym(inner) => self.emit_asm_sym(inner).map(Into::into), }?; - emit_detached!(AsmOperand, self, node, label); + post_emit!(AsmOperand, self, node, label); Some(label) } pub(crate) fn emit_asm_piece( &mut self, node: &ast::AsmPiece, ) -> Option> { + pre_emit!(AsmPiece, self, node); let label = match node { ast::AsmPiece::AsmClobberAbi(inner) => self.emit_asm_clobber_abi(inner).map(Into::into), ast::AsmPiece::AsmOperandNamed(inner) => { @@ -43,23 +45,25 @@ impl Translator<'_> { } ast::AsmPiece::AsmOptions(inner) => self.emit_asm_options(inner).map(Into::into), }?; - emit_detached!(AsmPiece, self, node, label); + post_emit!(AsmPiece, self, node, label); Some(label) } pub(crate) fn emit_assoc_item( &mut self, node: &ast::AssocItem, ) -> Option> { + pre_emit!(AssocItem, self, node); let label = match node { ast::AssocItem::Const(inner) => self.emit_const(inner).map(Into::into), ast::AssocItem::Fn(inner) => self.emit_fn(inner).map(Into::into), ast::AssocItem::MacroCall(inner) => self.emit_macro_call(inner).map(Into::into), ast::AssocItem::TypeAlias(inner) => self.emit_type_alias(inner).map(Into::into), }?; - emit_detached!(AssocItem, self, node, label); + post_emit!(AssocItem, self, node, label); Some(label) } pub(crate) fn emit_expr(&mut self, node: &ast::Expr) -> Option> { + pre_emit!(Expr, self, node); let label = match node { ast::Expr::ArrayExpr(inner) => self.emit_array_expr(inner).map(Into::into), ast::Expr::AsmExpr(inner) => self.emit_asm_expr(inner).map(Into::into), @@ -98,26 +102,28 @@ impl Translator<'_> { ast::Expr::YeetExpr(inner) => self.emit_yeet_expr(inner).map(Into::into), ast::Expr::YieldExpr(inner) => self.emit_yield_expr(inner).map(Into::into), }?; - emit_detached!(Expr, self, node, label); + post_emit!(Expr, self, node, label); Some(label) } pub(crate) fn emit_extern_item( &mut self, node: &ast::ExternItem, ) -> Option> { + pre_emit!(ExternItem, self, node); let label = match node { ast::ExternItem::Fn(inner) => self.emit_fn(inner).map(Into::into), ast::ExternItem::MacroCall(inner) => self.emit_macro_call(inner).map(Into::into), ast::ExternItem::Static(inner) => self.emit_static(inner).map(Into::into), ast::ExternItem::TypeAlias(inner) => self.emit_type_alias(inner).map(Into::into), }?; - emit_detached!(ExternItem, self, node, label); + post_emit!(ExternItem, self, node, label); Some(label) } pub(crate) fn emit_field_list( &mut self, node: &ast::FieldList, ) -> Option> { + pre_emit!(FieldList, self, node); let label = match node { ast::FieldList::RecordFieldList(inner) => { self.emit_record_field_list(inner).map(Into::into) @@ -126,26 +132,28 @@ impl Translator<'_> { self.emit_tuple_field_list(inner).map(Into::into) } }?; - emit_detached!(FieldList, self, node, label); + post_emit!(FieldList, self, node, label); Some(label) } pub(crate) fn emit_generic_arg( &mut self, node: &ast::GenericArg, ) -> Option> { + pre_emit!(GenericArg, self, node); let label = match node { ast::GenericArg::AssocTypeArg(inner) => self.emit_assoc_type_arg(inner).map(Into::into), ast::GenericArg::ConstArg(inner) => self.emit_const_arg(inner).map(Into::into), ast::GenericArg::LifetimeArg(inner) => self.emit_lifetime_arg(inner).map(Into::into), ast::GenericArg::TypeArg(inner) => self.emit_type_arg(inner).map(Into::into), }?; - emit_detached!(GenericArg, self, node, label); + post_emit!(GenericArg, self, node, label); Some(label) } pub(crate) fn emit_generic_param( &mut self, node: &ast::GenericParam, ) -> Option> { + pre_emit!(GenericParam, self, node); let label = match node { ast::GenericParam::ConstParam(inner) => self.emit_const_param(inner).map(Into::into), ast::GenericParam::LifetimeParam(inner) => { @@ -153,10 +161,11 @@ impl Translator<'_> { } ast::GenericParam::TypeParam(inner) => self.emit_type_param(inner).map(Into::into), }?; - emit_detached!(GenericParam, self, node, label); + post_emit!(GenericParam, self, node, label); Some(label) } pub(crate) fn emit_pat(&mut self, node: &ast::Pat) -> Option> { + pre_emit!(Pat, self, node); let label = match node { ast::Pat::BoxPat(inner) => self.emit_box_pat(inner).map(Into::into), ast::Pat::ConstBlockPat(inner) => self.emit_const_block_pat(inner).map(Into::into), @@ -175,19 +184,21 @@ impl Translator<'_> { ast::Pat::TupleStructPat(inner) => self.emit_tuple_struct_pat(inner).map(Into::into), ast::Pat::WildcardPat(inner) => self.emit_wildcard_pat(inner).map(Into::into), }?; - emit_detached!(Pat, self, node, label); + post_emit!(Pat, self, node, label); Some(label) } pub(crate) fn emit_stmt(&mut self, node: &ast::Stmt) -> Option> { + pre_emit!(Stmt, self, node); let label = match node { ast::Stmt::ExprStmt(inner) => self.emit_expr_stmt(inner).map(Into::into), ast::Stmt::Item(inner) => self.emit_item(inner).map(Into::into), ast::Stmt::LetStmt(inner) => self.emit_let_stmt(inner).map(Into::into), }?; - emit_detached!(Stmt, self, node, label); + post_emit!(Stmt, self, node, label); Some(label) } pub(crate) fn emit_type(&mut self, node: &ast::Type) -> Option> { + pre_emit!(TypeRepr, self, node); let label = match node { ast::Type::ArrayType(inner) => self.emit_array_type(inner).map(Into::into), ast::Type::DynTraitType(inner) => self.emit_dyn_trait_type(inner).map(Into::into), @@ -204,21 +215,23 @@ impl Translator<'_> { ast::Type::SliceType(inner) => self.emit_slice_type(inner).map(Into::into), ast::Type::TupleType(inner) => self.emit_tuple_type(inner).map(Into::into), }?; - emit_detached!(TypeRepr, self, node, label); + post_emit!(TypeRepr, self, node, label); Some(label) } pub(crate) fn emit_use_bound_generic_arg( &mut self, node: &ast::UseBoundGenericArg, ) -> Option> { + pre_emit!(UseBoundGenericArg, self, node); let label = match node { ast::UseBoundGenericArg::Lifetime(inner) => self.emit_lifetime(inner).map(Into::into), ast::UseBoundGenericArg::NameRef(inner) => self.emit_name_ref(inner).map(Into::into), }?; - emit_detached!(UseBoundGenericArg, self, node, label); + post_emit!(UseBoundGenericArg, self, node, label); Some(label) } pub(crate) fn emit_item(&mut self, node: &ast::Item) -> Option> { + pre_emit!(Item, self, node); let label = match node { ast::Item::Const(inner) => self.emit_const(inner).map(Into::into), ast::Item::Enum(inner) => self.emit_enum(inner).map(Into::into), @@ -238,17 +251,18 @@ impl Translator<'_> { ast::Item::Union(inner) => self.emit_union(inner).map(Into::into), ast::Item::Use(inner) => self.emit_use(inner).map(Into::into), }?; - emit_detached!(Item, self, node, label); + post_emit!(Item, self, node, label); Some(label) } pub(crate) fn emit_abi(&mut self, node: &ast::Abi) -> Option> { + pre_emit!(Abi, self, node); let abi_string = node.try_get_text(); let label = self.trap.emit(generated::Abi { id: TrapId::Star, abi_string, }); self.emit_location(label, node); - emit_detached!(Abi, self, node, label); + post_emit!(Abi, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -256,13 +270,14 @@ impl Translator<'_> { &mut self, node: &ast::ArgList, ) -> Option> { + pre_emit!(ArgList, self, node); let args = node.args().filter_map(|x| self.emit_expr(&x)).collect(); let label = self.trap.emit(generated::ArgList { id: TrapId::Star, args, }); self.emit_location(label, node); - emit_detached!(ArgList, self, node, label); + post_emit!(ArgList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -270,6 +285,7 @@ impl Translator<'_> { &mut self, node: &ast::ArrayExpr, ) -> Option> { + pre_emit!(ArrayExprInternal, self, node); if self.should_be_excluded(node) { return None; } @@ -283,7 +299,7 @@ impl Translator<'_> { is_semicolon, }); self.emit_location(label, node); - emit_detached!(ArrayExprInternal, self, node, label); + post_emit!(ArrayExprInternal, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -291,6 +307,7 @@ impl Translator<'_> { &mut self, node: &ast::ArrayType, ) -> Option> { + pre_emit!(ArrayTypeRepr, self, node); let const_arg = node.const_arg().and_then(|x| self.emit_const_arg(&x)); let element_type_repr = node.ty().and_then(|x| self.emit_type(&x)); let label = self.trap.emit(generated::ArrayTypeRepr { @@ -299,7 +316,7 @@ impl Translator<'_> { element_type_repr, }); self.emit_location(label, node); - emit_detached!(ArrayTypeRepr, self, node, label); + post_emit!(ArrayTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -307,11 +324,12 @@ impl Translator<'_> { &mut self, node: &ast::AsmClobberAbi, ) -> Option> { + pre_emit!(AsmClobberAbi, self, node); let label = self .trap .emit(generated::AsmClobberAbi { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(AsmClobberAbi, self, node, label); + post_emit!(AsmClobberAbi, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -319,6 +337,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmConst, ) -> Option> { + pre_emit!(AsmConst, self, node); let expr = node.expr().and_then(|x| self.emit_expr(&x)); let is_const = node.const_token().is_some(); let label = self.trap.emit(generated::AsmConst { @@ -327,7 +346,7 @@ impl Translator<'_> { is_const, }); self.emit_location(label, node); - emit_detached!(AsmConst, self, node, label); + post_emit!(AsmConst, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -335,9 +354,10 @@ impl Translator<'_> { &mut self, node: &ast::AsmDirSpec, ) -> Option> { + pre_emit!(AsmDirSpec, self, node); let label = self.trap.emit(generated::AsmDirSpec { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(AsmDirSpec, self, node, label); + post_emit!(AsmDirSpec, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -345,6 +365,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmExpr, ) -> Option> { + pre_emit!(AsmExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -361,7 +382,7 @@ impl Translator<'_> { template, }); self.emit_location(label, node); - emit_detached!(AsmExpr, self, node, label); + post_emit!(AsmExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -369,13 +390,14 @@ impl Translator<'_> { &mut self, node: &ast::AsmLabel, ) -> Option> { + pre_emit!(AsmLabel, self, node); let block_expr = node.block_expr().and_then(|x| self.emit_block_expr(&x)); let label = self.trap.emit(generated::AsmLabel { id: TrapId::Star, block_expr, }); self.emit_location(label, node); - emit_detached!(AsmLabel, self, node, label); + post_emit!(AsmLabel, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -383,6 +405,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmOperandExpr, ) -> Option> { + pre_emit!(AsmOperandExpr, self, node); let in_expr = node.in_expr().and_then(|x| self.emit_expr(&x)); let out_expr = node.out_expr().and_then(|x| self.emit_expr(&x)); let label = self.trap.emit(generated::AsmOperandExpr { @@ -391,7 +414,7 @@ impl Translator<'_> { out_expr, }); self.emit_location(label, node); - emit_detached!(AsmOperandExpr, self, node, label); + post_emit!(AsmOperandExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -399,6 +422,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmOperandNamed, ) -> Option> { + pre_emit!(AsmOperandNamed, self, node); let asm_operand = node.asm_operand().and_then(|x| self.emit_asm_operand(&x)); let name = node.name().and_then(|x| self.emit_name(&x)); let label = self.trap.emit(generated::AsmOperandNamed { @@ -407,7 +431,7 @@ impl Translator<'_> { name, }); self.emit_location(label, node); - emit_detached!(AsmOperandNamed, self, node, label); + post_emit!(AsmOperandNamed, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -415,13 +439,14 @@ impl Translator<'_> { &mut self, node: &ast::AsmOption, ) -> Option> { + pre_emit!(AsmOption, self, node); let is_raw = node.raw_token().is_some(); let label = self.trap.emit(generated::AsmOption { id: TrapId::Star, is_raw, }); self.emit_location(label, node); - emit_detached!(AsmOption, self, node, label); + post_emit!(AsmOption, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -429,6 +454,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmOptions, ) -> Option> { + pre_emit!(AsmOptionsList, self, node); let asm_options = node .asm_options() .filter_map(|x| self.emit_asm_option(&x)) @@ -438,7 +464,7 @@ impl Translator<'_> { asm_options, }); self.emit_location(label, node); - emit_detached!(AsmOptionsList, self, node, label); + post_emit!(AsmOptionsList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -446,6 +472,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmRegOperand, ) -> Option> { + pre_emit!(AsmRegOperand, self, node); let asm_dir_spec = node.asm_dir_spec().and_then(|x| self.emit_asm_dir_spec(&x)); let asm_operand_expr = node .asm_operand_expr() @@ -458,7 +485,7 @@ impl Translator<'_> { asm_reg_spec, }); self.emit_location(label, node); - emit_detached!(AsmRegOperand, self, node, label); + post_emit!(AsmRegOperand, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -466,24 +493,26 @@ impl Translator<'_> { &mut self, node: &ast::AsmRegSpec, ) -> Option> { + pre_emit!(AsmRegSpec, self, node); let identifier = node.name_ref().and_then(|x| self.emit_name_ref(&x)); let label = self.trap.emit(generated::AsmRegSpec { id: TrapId::Star, identifier, }); self.emit_location(label, node); - emit_detached!(AsmRegSpec, self, node, label); + post_emit!(AsmRegSpec, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_asm_sym(&mut self, node: &ast::AsmSym) -> Option> { + pre_emit!(AsmSym, self, node); let path = node.path().and_then(|x| self.emit_path(&x)); let label = self.trap.emit(generated::AsmSym { id: TrapId::Star, path, }); self.emit_location(label, node); - emit_detached!(AsmSym, self, node, label); + post_emit!(AsmSym, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -491,6 +520,7 @@ impl Translator<'_> { &mut self, node: &ast::AssocItemList, ) -> Option> { + pre_emit!(AssocItemList, self, node); if self.should_be_excluded(node) { return None; } @@ -505,7 +535,7 @@ impl Translator<'_> { attrs, }); self.emit_location(label, node); - emit_detached!(AssocItemList, self, node, label); + post_emit!(AssocItemList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -513,6 +543,7 @@ impl Translator<'_> { &mut self, node: &ast::AssocTypeArg, ) -> Option> { + pre_emit!(AssocTypeArg, self, node); let const_arg = node.const_arg().and_then(|x| self.emit_const_arg(&x)); let generic_arg_list = node .generic_arg_list() @@ -539,18 +570,19 @@ impl Translator<'_> { type_bound_list, }); self.emit_location(label, node); - emit_detached!(AssocTypeArg, self, node, label); + post_emit!(AssocTypeArg, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_attr(&mut self, node: &ast::Attr) -> Option> { + pre_emit!(Attr, self, node); let meta = node.meta().and_then(|x| self.emit_meta(&x)); let label = self.trap.emit(generated::Attr { id: TrapId::Star, meta, }); self.emit_location(label, node); - emit_detached!(Attr, self, node, label); + post_emit!(Attr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -558,6 +590,7 @@ impl Translator<'_> { &mut self, node: &ast::AwaitExpr, ) -> Option> { + pre_emit!(AwaitExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -569,7 +602,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(AwaitExpr, self, node, label); + post_emit!(AwaitExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -577,6 +610,7 @@ impl Translator<'_> { &mut self, node: &ast::BecomeExpr, ) -> Option> { + pre_emit!(BecomeExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -588,7 +622,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(BecomeExpr, self, node, label); + post_emit!(BecomeExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -596,6 +630,7 @@ impl Translator<'_> { &mut self, node: &ast::BinExpr, ) -> Option> { + pre_emit!(BinaryExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -611,7 +646,7 @@ impl Translator<'_> { rhs, }); self.emit_location(label, node); - emit_detached!(BinaryExpr, self, node, label); + post_emit!(BinaryExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -619,6 +654,7 @@ impl Translator<'_> { &mut self, node: &ast::BlockExpr, ) -> Option> { + pre_emit!(BlockExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -644,18 +680,19 @@ impl Translator<'_> { stmt_list, }); self.emit_location(label, node); - emit_detached!(BlockExpr, self, node, label); + post_emit!(BlockExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_box_pat(&mut self, node: &ast::BoxPat) -> Option> { + pre_emit!(BoxPat, self, node); let pat = node.pat().and_then(|x| self.emit_pat(&x)); let label = self.trap.emit(generated::BoxPat { id: TrapId::Star, pat, }); self.emit_location(label, node); - emit_detached!(BoxPat, self, node, label); + post_emit!(BoxPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -663,6 +700,7 @@ impl Translator<'_> { &mut self, node: &ast::BreakExpr, ) -> Option> { + pre_emit!(BreakExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -676,7 +714,7 @@ impl Translator<'_> { lifetime, }); self.emit_location(label, node); - emit_detached!(BreakExpr, self, node, label); + post_emit!(BreakExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -684,6 +722,7 @@ impl Translator<'_> { &mut self, node: &ast::CallExpr, ) -> Option> { + pre_emit!(CallExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -697,7 +736,7 @@ impl Translator<'_> { function, }); self.emit_location(label, node); - emit_detached!(CallExpr, self, node, label); + post_emit!(CallExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -705,6 +744,7 @@ impl Translator<'_> { &mut self, node: &ast::CastExpr, ) -> Option> { + pre_emit!(CastExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -718,7 +758,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(CastExpr, self, node, label); + post_emit!(CastExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -726,6 +766,7 @@ impl Translator<'_> { &mut self, node: &ast::ClosureBinder, ) -> Option> { + pre_emit!(ClosureBinder, self, node); let generic_param_list = node .generic_param_list() .and_then(|x| self.emit_generic_param_list(&x)); @@ -734,7 +775,7 @@ impl Translator<'_> { generic_param_list, }); self.emit_location(label, node); - emit_detached!(ClosureBinder, self, node, label); + post_emit!(ClosureBinder, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -742,6 +783,7 @@ impl Translator<'_> { &mut self, node: &ast::ClosureExpr, ) -> Option> { + pre_emit!(ClosureExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -771,11 +813,12 @@ impl Translator<'_> { ret_type, }); self.emit_location(label, node); - emit_detached!(ClosureExpr, self, node, label); + post_emit!(ClosureExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_const(&mut self, node: &ast::Const) -> Option> { + pre_emit!(Const, self, node); if self.should_be_excluded(node) { return None; } @@ -797,7 +840,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(Const, self, node, label); + post_emit!(Const, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -805,13 +848,14 @@ impl Translator<'_> { &mut self, node: &ast::ConstArg, ) -> Option> { + pre_emit!(ConstArg, self, node); let expr = node.expr().and_then(|x| self.emit_expr(&x)); let label = self.trap.emit(generated::ConstArg { id: TrapId::Star, expr, }); self.emit_location(label, node); - emit_detached!(ConstArg, self, node, label); + post_emit!(ConstArg, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -819,6 +863,7 @@ impl Translator<'_> { &mut self, node: &ast::ConstBlockPat, ) -> Option> { + pre_emit!(ConstBlockPat, self, node); let block_expr = node.block_expr().and_then(|x| self.emit_block_expr(&x)); let is_const = node.const_token().is_some(); let label = self.trap.emit(generated::ConstBlockPat { @@ -827,7 +872,7 @@ impl Translator<'_> { is_const, }); self.emit_location(label, node); - emit_detached!(ConstBlockPat, self, node, label); + post_emit!(ConstBlockPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -835,6 +880,7 @@ impl Translator<'_> { &mut self, node: &ast::ConstParam, ) -> Option> { + pre_emit!(ConstParam, self, node); if self.should_be_excluded(node) { return None; } @@ -852,7 +898,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(ConstParam, self, node, label); + post_emit!(ConstParam, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -860,6 +906,7 @@ impl Translator<'_> { &mut self, node: &ast::ContinueExpr, ) -> Option> { + pre_emit!(ContinueExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -871,7 +918,7 @@ impl Translator<'_> { lifetime, }); self.emit_location(label, node); - emit_detached!(ContinueExpr, self, node, label); + post_emit!(ContinueExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -879,6 +926,7 @@ impl Translator<'_> { &mut self, node: &ast::DynTraitType, ) -> Option> { + pre_emit!(DynTraitTypeRepr, self, node); let type_bound_list = node .type_bound_list() .and_then(|x| self.emit_type_bound_list(&x)); @@ -887,11 +935,12 @@ impl Translator<'_> { type_bound_list, }); self.emit_location(label, node); - emit_detached!(DynTraitTypeRepr, self, node, label); + post_emit!(DynTraitTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_enum(&mut self, node: &ast::Enum) -> Option> { + pre_emit!(Enum, self, node); if self.should_be_excluded(node) { return None; } @@ -913,7 +962,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(Enum, self, node, label); + post_emit!(Enum, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -921,13 +970,14 @@ impl Translator<'_> { &mut self, node: &ast::ExprStmt, ) -> Option> { + pre_emit!(ExprStmt, self, node); let expr = node.expr().and_then(|x| self.emit_expr(&x)); let label = self.trap.emit(generated::ExprStmt { id: TrapId::Star, expr, }); self.emit_location(label, node); - emit_detached!(ExprStmt, self, node, label); + post_emit!(ExprStmt, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -935,6 +985,7 @@ impl Translator<'_> { &mut self, node: &ast::ExternBlock, ) -> Option> { + pre_emit!(ExternBlock, self, node); if self.should_be_excluded(node) { return None; } @@ -952,7 +1003,7 @@ impl Translator<'_> { is_unsafe, }); self.emit_location(label, node); - emit_detached!(ExternBlock, self, node, label); + post_emit!(ExternBlock, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -960,6 +1011,7 @@ impl Translator<'_> { &mut self, node: &ast::ExternCrate, ) -> Option> { + pre_emit!(ExternCrate, self, node); if self.should_be_excluded(node) { return None; } @@ -975,7 +1027,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(ExternCrate, self, node, label); + post_emit!(ExternCrate, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -983,6 +1035,7 @@ impl Translator<'_> { &mut self, node: &ast::ExternItemList, ) -> Option> { + pre_emit!(ExternItemList, self, node); if self.should_be_excluded(node) { return None; } @@ -997,7 +1050,7 @@ impl Translator<'_> { extern_items, }); self.emit_location(label, node); - emit_detached!(ExternItemList, self, node, label); + post_emit!(ExternItemList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1005,6 +1058,7 @@ impl Translator<'_> { &mut self, node: &ast::FieldExpr, ) -> Option> { + pre_emit!(FieldExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1018,11 +1072,12 @@ impl Translator<'_> { identifier, }); self.emit_location(label, node); - emit_detached!(FieldExpr, self, node, label); + post_emit!(FieldExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_fn(&mut self, node: &ast::Fn) -> Option> { + pre_emit!(Function, self, node); if self.should_be_excluded(node) { return None; } @@ -1060,7 +1115,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(Function, self, node, label); + post_emit!(Function, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1068,6 +1123,7 @@ impl Translator<'_> { &mut self, node: &ast::FnPtrType, ) -> Option> { + pre_emit!(FnPtrTypeRepr, self, node); let abi = node.abi().and_then(|x| self.emit_abi(&x)); let is_async = node.async_token().is_some(); let is_const = node.const_token().is_some(); @@ -1084,7 +1140,7 @@ impl Translator<'_> { ret_type, }); self.emit_location(label, node); - emit_detached!(FnPtrTypeRepr, self, node, label); + post_emit!(FnPtrTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1092,6 +1148,7 @@ impl Translator<'_> { &mut self, node: &ast::ForExpr, ) -> Option> { + pre_emit!(ForExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1109,7 +1166,7 @@ impl Translator<'_> { pat, }); self.emit_location(label, node); - emit_detached!(ForExpr, self, node, label); + post_emit!(ForExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1117,6 +1174,7 @@ impl Translator<'_> { &mut self, node: &ast::ForType, ) -> Option> { + pre_emit!(ForTypeRepr, self, node); let generic_param_list = node .generic_param_list() .and_then(|x| self.emit_generic_param_list(&x)); @@ -1127,7 +1185,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(ForTypeRepr, self, node, label); + post_emit!(ForTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1135,6 +1193,7 @@ impl Translator<'_> { &mut self, node: &ast::FormatArgsArg, ) -> Option> { + pre_emit!(FormatArgsArg, self, node); let expr = node.expr().and_then(|x| self.emit_expr(&x)); let name = node.name().and_then(|x| self.emit_name(&x)); let label = self.trap.emit(generated::FormatArgsArg { @@ -1143,7 +1202,7 @@ impl Translator<'_> { name, }); self.emit_location(label, node); - emit_detached!(FormatArgsArg, self, node, label); + post_emit!(FormatArgsArg, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1151,6 +1210,7 @@ impl Translator<'_> { &mut self, node: &ast::FormatArgsExpr, ) -> Option> { + pre_emit!(FormatArgsExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1167,7 +1227,7 @@ impl Translator<'_> { template, }); self.emit_location(label, node); - emit_detached!(FormatArgsExpr, self, node, label); + post_emit!(FormatArgsExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1175,6 +1235,7 @@ impl Translator<'_> { &mut self, node: &ast::GenericArgList, ) -> Option> { + pre_emit!(GenericArgList, self, node); let generic_args = node .generic_args() .filter_map(|x| self.emit_generic_arg(&x)) @@ -1184,7 +1245,7 @@ impl Translator<'_> { generic_args, }); self.emit_location(label, node); - emit_detached!(GenericArgList, self, node, label); + post_emit!(GenericArgList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1192,6 +1253,7 @@ impl Translator<'_> { &mut self, node: &ast::GenericParamList, ) -> Option> { + pre_emit!(GenericParamList, self, node); let generic_params = node .generic_params() .filter_map(|x| self.emit_generic_param(&x)) @@ -1201,7 +1263,7 @@ impl Translator<'_> { generic_params, }); self.emit_location(label, node); - emit_detached!(GenericParamList, self, node, label); + post_emit!(GenericParamList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1209,6 +1271,7 @@ impl Translator<'_> { &mut self, node: &ast::IdentPat, ) -> Option> { + pre_emit!(IdentPat, self, node); if self.should_be_excluded(node) { return None; } @@ -1226,11 +1289,12 @@ impl Translator<'_> { pat, }); self.emit_location(label, node); - emit_detached!(IdentPat, self, node, label); + post_emit!(IdentPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_if_expr(&mut self, node: &ast::IfExpr) -> Option> { + pre_emit!(IfExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1246,11 +1310,12 @@ impl Translator<'_> { then, }); self.emit_location(label, node); - emit_detached!(IfExpr, self, node, label); + post_emit!(IfExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_impl(&mut self, node: &ast::Impl) -> Option> { + pre_emit!(Impl, self, node); if self.should_be_excluded(node) { return None; } @@ -1282,7 +1347,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(Impl, self, node, label); + post_emit!(Impl, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1290,6 +1355,7 @@ impl Translator<'_> { &mut self, node: &ast::ImplTraitType, ) -> Option> { + pre_emit!(ImplTraitTypeRepr, self, node); let type_bound_list = node .type_bound_list() .and_then(|x| self.emit_type_bound_list(&x)); @@ -1298,7 +1364,7 @@ impl Translator<'_> { type_bound_list, }); self.emit_location(label, node); - emit_detached!(ImplTraitTypeRepr, self, node, label); + post_emit!(ImplTraitTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1306,6 +1372,7 @@ impl Translator<'_> { &mut self, node: &ast::IndexExpr, ) -> Option> { + pre_emit!(IndexExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1319,7 +1386,7 @@ impl Translator<'_> { index, }); self.emit_location(label, node); - emit_detached!(IndexExpr, self, node, label); + post_emit!(IndexExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1327,11 +1394,12 @@ impl Translator<'_> { &mut self, node: &ast::InferType, ) -> Option> { + pre_emit!(InferTypeRepr, self, node); let label = self .trap .emit(generated::InferTypeRepr { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(InferTypeRepr, self, node, label); + post_emit!(InferTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1339,6 +1407,7 @@ impl Translator<'_> { &mut self, node: &ast::ItemList, ) -> Option> { + pre_emit!(ItemList, self, node); if self.should_be_excluded(node) { return None; } @@ -1350,18 +1419,19 @@ impl Translator<'_> { items, }); self.emit_location(label, node); - emit_detached!(ItemList, self, node, label); + post_emit!(ItemList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_label(&mut self, node: &ast::Label) -> Option> { + pre_emit!(Label, self, node); let lifetime = node.lifetime().and_then(|x| self.emit_lifetime(&x)); let label = self.trap.emit(generated::Label { id: TrapId::Star, lifetime, }); self.emit_location(label, node); - emit_detached!(Label, self, node, label); + post_emit!(Label, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1369,13 +1439,14 @@ impl Translator<'_> { &mut self, node: &ast::LetElse, ) -> Option> { + pre_emit!(LetElse, self, node); let block_expr = node.block_expr().and_then(|x| self.emit_block_expr(&x)); let label = self.trap.emit(generated::LetElse { id: TrapId::Star, block_expr, }); self.emit_location(label, node); - emit_detached!(LetElse, self, node, label); + post_emit!(LetElse, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1383,6 +1454,7 @@ impl Translator<'_> { &mut self, node: &ast::LetExpr, ) -> Option> { + pre_emit!(LetExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1396,7 +1468,7 @@ impl Translator<'_> { pat, }); self.emit_location(label, node); - emit_detached!(LetExpr, self, node, label); + post_emit!(LetExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1404,6 +1476,7 @@ impl Translator<'_> { &mut self, node: &ast::LetStmt, ) -> Option> { + pre_emit!(LetStmt, self, node); if self.should_be_excluded(node) { return None; } @@ -1421,7 +1494,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(LetStmt, self, node, label); + post_emit!(LetStmt, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1429,13 +1502,14 @@ impl Translator<'_> { &mut self, node: &ast::Lifetime, ) -> Option> { + pre_emit!(Lifetime, self, node); let text = node.try_get_text(); let label = self.trap.emit(generated::Lifetime { id: TrapId::Star, text, }); self.emit_location(label, node); - emit_detached!(Lifetime, self, node, label); + post_emit!(Lifetime, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1443,13 +1517,14 @@ impl Translator<'_> { &mut self, node: &ast::LifetimeArg, ) -> Option> { + pre_emit!(LifetimeArg, self, node); let lifetime = node.lifetime().and_then(|x| self.emit_lifetime(&x)); let label = self.trap.emit(generated::LifetimeArg { id: TrapId::Star, lifetime, }); self.emit_location(label, node); - emit_detached!(LifetimeArg, self, node, label); + post_emit!(LifetimeArg, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1457,6 +1532,7 @@ impl Translator<'_> { &mut self, node: &ast::LifetimeParam, ) -> Option> { + pre_emit!(LifetimeParam, self, node); if self.should_be_excluded(node) { return None; } @@ -1472,7 +1548,7 @@ impl Translator<'_> { type_bound_list, }); self.emit_location(label, node); - emit_detached!(LifetimeParam, self, node, label); + post_emit!(LifetimeParam, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1480,6 +1556,7 @@ impl Translator<'_> { &mut self, node: &ast::Literal, ) -> Option> { + pre_emit!(LiteralExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1491,7 +1568,7 @@ impl Translator<'_> { text_value, }); self.emit_location(label, node); - emit_detached!(LiteralExpr, self, node, label); + post_emit!(LiteralExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1499,13 +1576,14 @@ impl Translator<'_> { &mut self, node: &ast::LiteralPat, ) -> Option> { + pre_emit!(LiteralPat, self, node); let literal = node.literal().and_then(|x| self.emit_literal(&x)); let label = self.trap.emit(generated::LiteralPat { id: TrapId::Star, literal, }); self.emit_location(label, node); - emit_detached!(LiteralPat, self, node, label); + post_emit!(LiteralPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1513,6 +1591,7 @@ impl Translator<'_> { &mut self, node: &ast::LoopExpr, ) -> Option> { + pre_emit!(LoopExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1526,7 +1605,7 @@ impl Translator<'_> { loop_body, }); self.emit_location(label, node); - emit_detached!(LoopExpr, self, node, label); + post_emit!(LoopExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1534,6 +1613,7 @@ impl Translator<'_> { &mut self, node: &ast::MacroCall, ) -> Option> { + pre_emit!(MacroCall, self, node); if self.should_be_excluded(node) { return None; } @@ -1547,7 +1627,7 @@ impl Translator<'_> { token_tree, }); self.emit_location(label, node); - emit_detached!(MacroCall, self, node, label); + post_emit!(MacroCall, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1555,6 +1635,7 @@ impl Translator<'_> { &mut self, node: &ast::MacroDef, ) -> Option> { + pre_emit!(MacroDef, self, node); if self.should_be_excluded(node) { return None; } @@ -1572,7 +1653,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(MacroDef, self, node, label); + post_emit!(MacroDef, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1580,13 +1661,14 @@ impl Translator<'_> { &mut self, node: &ast::MacroExpr, ) -> Option> { + pre_emit!(MacroExpr, self, node); let macro_call = node.macro_call().and_then(|x| self.emit_macro_call(&x)); let label = self.trap.emit(generated::MacroExpr { id: TrapId::Star, macro_call, }); self.emit_location(label, node); - emit_detached!(MacroExpr, self, node, label); + post_emit!(MacroExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1594,13 +1676,14 @@ impl Translator<'_> { &mut self, node: &ast::MacroItems, ) -> Option> { + pre_emit!(MacroItems, self, node); let items = node.items().filter_map(|x| self.emit_item(&x)).collect(); let label = self.trap.emit(generated::MacroItems { id: TrapId::Star, items, }); self.emit_location(label, node); - emit_detached!(MacroItems, self, node, label); + post_emit!(MacroItems, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1608,13 +1691,14 @@ impl Translator<'_> { &mut self, node: &ast::MacroPat, ) -> Option> { + pre_emit!(MacroPat, self, node); let macro_call = node.macro_call().and_then(|x| self.emit_macro_call(&x)); let label = self.trap.emit(generated::MacroPat { id: TrapId::Star, macro_call, }); self.emit_location(label, node); - emit_detached!(MacroPat, self, node, label); + post_emit!(MacroPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1622,6 +1706,7 @@ impl Translator<'_> { &mut self, node: &ast::MacroRules, ) -> Option> { + pre_emit!(MacroRules, self, node); if self.should_be_excluded(node) { return None; } @@ -1637,7 +1722,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(MacroRules, self, node, label); + post_emit!(MacroRules, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1645,6 +1730,7 @@ impl Translator<'_> { &mut self, node: &ast::MacroStmts, ) -> Option> { + pre_emit!(MacroBlockExpr, self, node); let tail_expr = node.expr().and_then(|x| self.emit_expr(&x)); let statements = node .statements() @@ -1656,7 +1742,7 @@ impl Translator<'_> { statements, }); self.emit_location(label, node); - emit_detached!(MacroBlockExpr, self, node, label); + post_emit!(MacroBlockExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1664,13 +1750,14 @@ impl Translator<'_> { &mut self, node: &ast::MacroType, ) -> Option> { + pre_emit!(MacroTypeRepr, self, node); let macro_call = node.macro_call().and_then(|x| self.emit_macro_call(&x)); let label = self.trap.emit(generated::MacroTypeRepr { id: TrapId::Star, macro_call, }); self.emit_location(label, node); - emit_detached!(MacroTypeRepr, self, node, label); + post_emit!(MacroTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1678,6 +1765,7 @@ impl Translator<'_> { &mut self, node: &ast::MatchArm, ) -> Option> { + pre_emit!(MatchArm, self, node); if self.should_be_excluded(node) { return None; } @@ -1693,7 +1781,7 @@ impl Translator<'_> { pat, }); self.emit_location(label, node); - emit_detached!(MatchArm, self, node, label); + post_emit!(MatchArm, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1701,6 +1789,7 @@ impl Translator<'_> { &mut self, node: &ast::MatchArmList, ) -> Option> { + pre_emit!(MatchArmList, self, node); if self.should_be_excluded(node) { return None; } @@ -1715,7 +1804,7 @@ impl Translator<'_> { attrs, }); self.emit_location(label, node); - emit_detached!(MatchArmList, self, node, label); + post_emit!(MatchArmList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1723,6 +1812,7 @@ impl Translator<'_> { &mut self, node: &ast::MatchExpr, ) -> Option> { + pre_emit!(MatchExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1738,7 +1828,7 @@ impl Translator<'_> { match_arm_list, }); self.emit_location(label, node); - emit_detached!(MatchExpr, self, node, label); + post_emit!(MatchExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1746,17 +1836,19 @@ impl Translator<'_> { &mut self, node: &ast::MatchGuard, ) -> Option> { + pre_emit!(MatchGuard, self, node); let condition = node.condition().and_then(|x| self.emit_expr(&x)); let label = self.trap.emit(generated::MatchGuard { id: TrapId::Star, condition, }); self.emit_location(label, node); - emit_detached!(MatchGuard, self, node, label); + post_emit!(MatchGuard, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_meta(&mut self, node: &ast::Meta) -> Option> { + pre_emit!(Meta, self, node); let expr = node.expr().and_then(|x| self.emit_expr(&x)); let is_unsafe = node.unsafe_token().is_some(); let path = node.path().and_then(|x| self.emit_path(&x)); @@ -1769,7 +1861,7 @@ impl Translator<'_> { token_tree, }); self.emit_location(label, node); - emit_detached!(Meta, self, node, label); + post_emit!(Meta, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1777,6 +1869,7 @@ impl Translator<'_> { &mut self, node: &ast::MethodCallExpr, ) -> Option> { + pre_emit!(MethodCallExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1796,11 +1889,12 @@ impl Translator<'_> { receiver, }); self.emit_location(label, node); - emit_detached!(MethodCallExpr, self, node, label); + post_emit!(MethodCallExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_module(&mut self, node: &ast::Module) -> Option> { + pre_emit!(Module, self, node); if self.should_be_excluded(node) { return None; } @@ -1816,18 +1910,19 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(Module, self, node, label); + post_emit!(Module, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_name(&mut self, node: &ast::Name) -> Option> { + pre_emit!(Name, self, node); let text = node.try_get_text(); let label = self.trap.emit(generated::Name { id: TrapId::Star, text, }); self.emit_location(label, node); - emit_detached!(Name, self, node, label); + post_emit!(Name, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1835,13 +1930,14 @@ impl Translator<'_> { &mut self, node: &ast::NameRef, ) -> Option> { + pre_emit!(NameRef, self, node); let text = node.try_get_text(); let label = self.trap.emit(generated::NameRef { id: TrapId::Star, text, }); self.emit_location(label, node); - emit_detached!(NameRef, self, node, label); + post_emit!(NameRef, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1849,11 +1945,12 @@ impl Translator<'_> { &mut self, node: &ast::NeverType, ) -> Option> { + pre_emit!(NeverTypeRepr, self, node); let label = self .trap .emit(generated::NeverTypeRepr { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(NeverTypeRepr, self, node, label); + post_emit!(NeverTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1861,6 +1958,7 @@ impl Translator<'_> { &mut self, node: &ast::OffsetOfExpr, ) -> Option> { + pre_emit!(OffsetOfExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1877,22 +1975,24 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(OffsetOfExpr, self, node, label); + post_emit!(OffsetOfExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_or_pat(&mut self, node: &ast::OrPat) -> Option> { + pre_emit!(OrPat, self, node); let pats = node.pats().filter_map(|x| self.emit_pat(&x)).collect(); let label = self.trap.emit(generated::OrPat { id: TrapId::Star, pats, }); self.emit_location(label, node); - emit_detached!(OrPat, self, node, label); + post_emit!(OrPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_param(&mut self, node: &ast::Param) -> Option> { + pre_emit!(Param, self, node); if self.should_be_excluded(node) { return None; } @@ -1906,7 +2006,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(Param, self, node, label); + post_emit!(Param, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1914,6 +2014,7 @@ impl Translator<'_> { &mut self, node: &ast::ParamList, ) -> Option> { + pre_emit!(ParamList, self, node); let params = node.params().filter_map(|x| self.emit_param(&x)).collect(); let self_param = node.self_param().and_then(|x| self.emit_self_param(&x)); let label = self.trap.emit(generated::ParamList { @@ -1922,7 +2023,7 @@ impl Translator<'_> { self_param, }); self.emit_location(label, node); - emit_detached!(ParamList, self, node, label); + post_emit!(ParamList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1930,6 +2031,7 @@ impl Translator<'_> { &mut self, node: &ast::ParenExpr, ) -> Option> { + pre_emit!(ParenExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1941,7 +2043,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(ParenExpr, self, node, label); + post_emit!(ParenExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1949,13 +2051,14 @@ impl Translator<'_> { &mut self, node: &ast::ParenPat, ) -> Option> { + pre_emit!(ParenPat, self, node); let pat = node.pat().and_then(|x| self.emit_pat(&x)); let label = self.trap.emit(generated::ParenPat { id: TrapId::Star, pat, }); self.emit_location(label, node); - emit_detached!(ParenPat, self, node, label); + post_emit!(ParenPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1963,13 +2066,14 @@ impl Translator<'_> { &mut self, node: &ast::ParenType, ) -> Option> { + pre_emit!(ParenTypeRepr, self, node); let type_repr = node.ty().and_then(|x| self.emit_type(&x)); let label = self.trap.emit(generated::ParenTypeRepr { id: TrapId::Star, type_repr, }); self.emit_location(label, node); - emit_detached!(ParenTypeRepr, self, node, label); + post_emit!(ParenTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1977,6 +2081,7 @@ impl Translator<'_> { &mut self, node: &ast::ParenthesizedArgList, ) -> Option> { + pre_emit!(ParenthesizedArgList, self, node); let type_args = node .type_args() .filter_map(|x| self.emit_type_arg(&x)) @@ -1986,11 +2091,12 @@ impl Translator<'_> { type_args, }); self.emit_location(label, node); - emit_detached!(ParenthesizedArgList, self, node, label); + post_emit!(ParenthesizedArgList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_path(&mut self, node: &ast::Path) -> Option> { + pre_emit!(Path, self, node); let qualifier = node.qualifier().and_then(|x| self.emit_path(&x)); let segment = node.segment().and_then(|x| self.emit_path_segment(&x)); let label = self.trap.emit(generated::Path { @@ -1999,7 +2105,7 @@ impl Translator<'_> { segment, }); self.emit_location(label, node); - emit_detached!(Path, self, node, label); + post_emit!(Path, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2007,6 +2113,7 @@ impl Translator<'_> { &mut self, node: &ast::PathExpr, ) -> Option> { + pre_emit!(PathExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2018,7 +2125,7 @@ impl Translator<'_> { path, }); self.emit_location(label, node); - emit_detached!(PathExpr, self, node, label); + post_emit!(PathExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2026,13 +2133,14 @@ impl Translator<'_> { &mut self, node: &ast::PathPat, ) -> Option> { + pre_emit!(PathPat, self, node); let path = node.path().and_then(|x| self.emit_path(&x)); let label = self.trap.emit(generated::PathPat { id: TrapId::Star, path, }); self.emit_location(label, node); - emit_detached!(PathPat, self, node, label); + post_emit!(PathPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2040,6 +2148,7 @@ impl Translator<'_> { &mut self, node: &ast::PathSegment, ) -> Option> { + pre_emit!(PathSegment, self, node); let generic_arg_list = node .generic_arg_list() .and_then(|x| self.emit_generic_arg_list(&x)); @@ -2060,7 +2169,7 @@ impl Translator<'_> { return_type_syntax, }); self.emit_location(label, node); - emit_detached!(PathSegment, self, node, label); + post_emit!(PathSegment, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2068,13 +2177,14 @@ impl Translator<'_> { &mut self, node: &ast::PathType, ) -> Option> { + pre_emit!(PathTypeRepr, self, node); let path = node.path().and_then(|x| self.emit_path(&x)); let label = self.trap.emit(generated::PathTypeRepr { id: TrapId::Star, path, }); self.emit_location(label, node); - emit_detached!(PathTypeRepr, self, node, label); + post_emit!(PathTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2082,6 +2192,7 @@ impl Translator<'_> { &mut self, node: &ast::PrefixExpr, ) -> Option> { + pre_emit!(PrefixExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2095,7 +2206,7 @@ impl Translator<'_> { operator_name, }); self.emit_location(label, node); - emit_detached!(PrefixExpr, self, node, label); + post_emit!(PrefixExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2103,6 +2214,7 @@ impl Translator<'_> { &mut self, node: &ast::PtrType, ) -> Option> { + pre_emit!(PtrTypeRepr, self, node); let is_const = node.const_token().is_some(); let is_mut = node.mut_token().is_some(); let type_repr = node.ty().and_then(|x| self.emit_type(&x)); @@ -2113,7 +2225,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(PtrTypeRepr, self, node, label); + post_emit!(PtrTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2121,6 +2233,7 @@ impl Translator<'_> { &mut self, node: &ast::RangeExpr, ) -> Option> { + pre_emit!(RangeExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2136,7 +2249,7 @@ impl Translator<'_> { start, }); self.emit_location(label, node); - emit_detached!(RangeExpr, self, node, label); + post_emit!(RangeExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2144,6 +2257,7 @@ impl Translator<'_> { &mut self, node: &ast::RangePat, ) -> Option> { + pre_emit!(RangePat, self, node); let end = node.end().and_then(|x| self.emit_pat(&x)); let operator_name = node.try_get_text(); let start = node.start().and_then(|x| self.emit_pat(&x)); @@ -2154,7 +2268,7 @@ impl Translator<'_> { start, }); self.emit_location(label, node); - emit_detached!(RangePat, self, node, label); + post_emit!(RangePat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2162,6 +2276,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordExpr, ) -> Option> { + pre_emit!(StructExpr, self, node); let path = node.path().and_then(|x| self.emit_path(&x)); let struct_expr_field_list = node .record_expr_field_list() @@ -2172,7 +2287,7 @@ impl Translator<'_> { struct_expr_field_list, }); self.emit_location(label, node); - emit_detached!(StructExpr, self, node, label); + post_emit!(StructExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2180,6 +2295,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordExprField, ) -> Option> { + pre_emit!(StructExprField, self, node); if self.should_be_excluded(node) { return None; } @@ -2193,7 +2309,7 @@ impl Translator<'_> { identifier, }); self.emit_location(label, node); - emit_detached!(StructExprField, self, node, label); + post_emit!(StructExprField, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2201,6 +2317,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordExprFieldList, ) -> Option> { + pre_emit!(StructExprFieldList, self, node); if self.should_be_excluded(node) { return None; } @@ -2217,7 +2334,7 @@ impl Translator<'_> { spread, }); self.emit_location(label, node); - emit_detached!(StructExprFieldList, self, node, label); + post_emit!(StructExprFieldList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2225,6 +2342,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordField, ) -> Option> { + pre_emit!(StructField, self, node); if self.should_be_excluded(node) { return None; } @@ -2244,7 +2362,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(StructField, self, node, label); + post_emit!(StructField, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2252,6 +2370,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordFieldList, ) -> Option> { + pre_emit!(StructFieldList, self, node); let fields = node .fields() .filter_map(|x| self.emit_record_field(&x)) @@ -2261,7 +2380,7 @@ impl Translator<'_> { fields, }); self.emit_location(label, node); - emit_detached!(StructFieldList, self, node, label); + post_emit!(StructFieldList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2269,6 +2388,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordPat, ) -> Option> { + pre_emit!(StructPat, self, node); let path = node.path().and_then(|x| self.emit_path(&x)); let struct_pat_field_list = node .record_pat_field_list() @@ -2279,7 +2399,7 @@ impl Translator<'_> { struct_pat_field_list, }); self.emit_location(label, node); - emit_detached!(StructPat, self, node, label); + post_emit!(StructPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2287,6 +2407,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordPatField, ) -> Option> { + pre_emit!(StructPatField, self, node); if self.should_be_excluded(node) { return None; } @@ -2300,7 +2421,7 @@ impl Translator<'_> { pat, }); self.emit_location(label, node); - emit_detached!(StructPatField, self, node, label); + post_emit!(StructPatField, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2308,6 +2429,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordPatFieldList, ) -> Option> { + pre_emit!(StructPatFieldList, self, node); let fields = node .fields() .filter_map(|x| self.emit_record_pat_field(&x)) @@ -2319,7 +2441,7 @@ impl Translator<'_> { rest_pat, }); self.emit_location(label, node); - emit_detached!(StructPatFieldList, self, node, label); + post_emit!(StructPatFieldList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2327,6 +2449,7 @@ impl Translator<'_> { &mut self, node: &ast::RefExpr, ) -> Option> { + pre_emit!(RefExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2344,11 +2467,12 @@ impl Translator<'_> { is_raw, }); self.emit_location(label, node); - emit_detached!(RefExpr, self, node, label); + post_emit!(RefExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_ref_pat(&mut self, node: &ast::RefPat) -> Option> { + pre_emit!(RefPat, self, node); let is_mut = node.mut_token().is_some(); let pat = node.pat().and_then(|x| self.emit_pat(&x)); let label = self.trap.emit(generated::RefPat { @@ -2357,7 +2481,7 @@ impl Translator<'_> { pat, }); self.emit_location(label, node); - emit_detached!(RefPat, self, node, label); + post_emit!(RefPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2365,6 +2489,7 @@ impl Translator<'_> { &mut self, node: &ast::RefType, ) -> Option> { + pre_emit!(RefTypeRepr, self, node); let is_mut = node.mut_token().is_some(); let lifetime = node.lifetime().and_then(|x| self.emit_lifetime(&x)); let type_repr = node.ty().and_then(|x| self.emit_type(&x)); @@ -2375,18 +2500,19 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(RefTypeRepr, self, node, label); + post_emit!(RefTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_rename(&mut self, node: &ast::Rename) -> Option> { + pre_emit!(Rename, self, node); let name = node.name().and_then(|x| self.emit_name(&x)); let label = self.trap.emit(generated::Rename { id: TrapId::Star, name, }); self.emit_location(label, node); - emit_detached!(Rename, self, node, label); + post_emit!(Rename, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2394,6 +2520,7 @@ impl Translator<'_> { &mut self, node: &ast::RestPat, ) -> Option> { + pre_emit!(RestPat, self, node); if self.should_be_excluded(node) { return None; } @@ -2403,7 +2530,7 @@ impl Translator<'_> { attrs, }); self.emit_location(label, node); - emit_detached!(RestPat, self, node, label); + post_emit!(RestPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2411,13 +2538,14 @@ impl Translator<'_> { &mut self, node: &ast::RetType, ) -> Option> { + pre_emit!(RetTypeRepr, self, node); let type_repr = node.ty().and_then(|x| self.emit_type(&x)); let label = self.trap.emit(generated::RetTypeRepr { id: TrapId::Star, type_repr, }); self.emit_location(label, node); - emit_detached!(RetTypeRepr, self, node, label); + post_emit!(RetTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2425,6 +2553,7 @@ impl Translator<'_> { &mut self, node: &ast::ReturnExpr, ) -> Option> { + pre_emit!(ReturnExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2436,7 +2565,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(ReturnExpr, self, node, label); + post_emit!(ReturnExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2444,11 +2573,12 @@ impl Translator<'_> { &mut self, node: &ast::ReturnTypeSyntax, ) -> Option> { + pre_emit!(ReturnTypeSyntax, self, node); let label = self .trap .emit(generated::ReturnTypeSyntax { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(ReturnTypeSyntax, self, node, label); + post_emit!(ReturnTypeSyntax, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2456,6 +2586,7 @@ impl Translator<'_> { &mut self, node: &ast::SelfParam, ) -> Option> { + pre_emit!(SelfParam, self, node); if self.should_be_excluded(node) { return None; } @@ -2475,7 +2606,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(SelfParam, self, node, label); + post_emit!(SelfParam, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2483,13 +2614,14 @@ impl Translator<'_> { &mut self, node: &ast::SlicePat, ) -> Option> { + pre_emit!(SlicePat, self, node); let pats = node.pats().filter_map(|x| self.emit_pat(&x)).collect(); let label = self.trap.emit(generated::SlicePat { id: TrapId::Star, pats, }); self.emit_location(label, node); - emit_detached!(SlicePat, self, node, label); + post_emit!(SlicePat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2497,13 +2629,14 @@ impl Translator<'_> { &mut self, node: &ast::SliceType, ) -> Option> { + pre_emit!(SliceTypeRepr, self, node); let type_repr = node.ty().and_then(|x| self.emit_type(&x)); let label = self.trap.emit(generated::SliceTypeRepr { id: TrapId::Star, type_repr, }); self.emit_location(label, node); - emit_detached!(SliceTypeRepr, self, node, label); + post_emit!(SliceTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2511,6 +2644,7 @@ impl Translator<'_> { &mut self, node: &ast::SourceFile, ) -> Option> { + pre_emit!(SourceFile, self, node); if self.should_be_excluded(node) { return None; } @@ -2522,11 +2656,12 @@ impl Translator<'_> { items, }); self.emit_location(label, node); - emit_detached!(SourceFile, self, node, label); + post_emit!(SourceFile, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_static(&mut self, node: &ast::Static) -> Option> { + pre_emit!(Static, self, node); if self.should_be_excluded(node) { return None; } @@ -2550,7 +2685,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(Static, self, node, label); + post_emit!(Static, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2558,6 +2693,7 @@ impl Translator<'_> { &mut self, node: &ast::StmtList, ) -> Option> { + pre_emit!(StmtList, self, node); if self.should_be_excluded(node) { return None; } @@ -2574,11 +2710,12 @@ impl Translator<'_> { tail_expr, }); self.emit_location(label, node); - emit_detached!(StmtList, self, node, label); + post_emit!(StmtList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_struct(&mut self, node: &ast::Struct) -> Option> { + pre_emit!(Struct, self, node); if self.should_be_excluded(node) { return None; } @@ -2600,7 +2737,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(Struct, self, node, label); + post_emit!(Struct, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2608,13 +2745,15 @@ impl Translator<'_> { &mut self, node: &ast::TokenTree, ) -> Option> { + pre_emit!(TokenTree, self, node); let label = self.trap.emit(generated::TokenTree { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(TokenTree, self, node, label); + post_emit!(TokenTree, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_trait(&mut self, node: &ast::Trait) -> Option> { + pre_emit!(Trait, self, node); if self.should_be_excluded(node) { return None; } @@ -2646,7 +2785,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(Trait, self, node, label); + post_emit!(Trait, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2654,6 +2793,7 @@ impl Translator<'_> { &mut self, node: &ast::TraitAlias, ) -> Option> { + pre_emit!(TraitAlias, self, node); if self.should_be_excluded(node) { return None; } @@ -2677,7 +2817,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(TraitAlias, self, node, label); + post_emit!(TraitAlias, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2685,6 +2825,7 @@ impl Translator<'_> { &mut self, node: &ast::TryExpr, ) -> Option> { + pre_emit!(TryExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2696,7 +2837,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(TryExpr, self, node, label); + post_emit!(TryExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2704,6 +2845,7 @@ impl Translator<'_> { &mut self, node: &ast::TupleExpr, ) -> Option> { + pre_emit!(TupleExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2715,7 +2857,7 @@ impl Translator<'_> { fields, }); self.emit_location(label, node); - emit_detached!(TupleExpr, self, node, label); + post_emit!(TupleExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2723,6 +2865,7 @@ impl Translator<'_> { &mut self, node: &ast::TupleField, ) -> Option> { + pre_emit!(TupleField, self, node); if self.should_be_excluded(node) { return None; } @@ -2736,7 +2879,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(TupleField, self, node, label); + post_emit!(TupleField, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2744,6 +2887,7 @@ impl Translator<'_> { &mut self, node: &ast::TupleFieldList, ) -> Option> { + pre_emit!(TupleFieldList, self, node); let fields = node .fields() .filter_map(|x| self.emit_tuple_field(&x)) @@ -2753,7 +2897,7 @@ impl Translator<'_> { fields, }); self.emit_location(label, node); - emit_detached!(TupleFieldList, self, node, label); + post_emit!(TupleFieldList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2761,13 +2905,14 @@ impl Translator<'_> { &mut self, node: &ast::TuplePat, ) -> Option> { + pre_emit!(TuplePat, self, node); let fields = node.fields().filter_map(|x| self.emit_pat(&x)).collect(); let label = self.trap.emit(generated::TuplePat { id: TrapId::Star, fields, }); self.emit_location(label, node); - emit_detached!(TuplePat, self, node, label); + post_emit!(TuplePat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2775,6 +2920,7 @@ impl Translator<'_> { &mut self, node: &ast::TupleStructPat, ) -> Option> { + pre_emit!(TupleStructPat, self, node); let fields = node.fields().filter_map(|x| self.emit_pat(&x)).collect(); let path = node.path().and_then(|x| self.emit_path(&x)); let label = self.trap.emit(generated::TupleStructPat { @@ -2783,7 +2929,7 @@ impl Translator<'_> { path, }); self.emit_location(label, node); - emit_detached!(TupleStructPat, self, node, label); + post_emit!(TupleStructPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2791,13 +2937,14 @@ impl Translator<'_> { &mut self, node: &ast::TupleType, ) -> Option> { + pre_emit!(TupleTypeRepr, self, node); let fields = node.fields().filter_map(|x| self.emit_type(&x)).collect(); let label = self.trap.emit(generated::TupleTypeRepr { id: TrapId::Star, fields, }); self.emit_location(label, node); - emit_detached!(TupleTypeRepr, self, node, label); + post_emit!(TupleTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2805,6 +2952,7 @@ impl Translator<'_> { &mut self, node: &ast::TypeAlias, ) -> Option> { + pre_emit!(TypeAlias, self, node); if self.should_be_excluded(node) { return None; } @@ -2832,7 +2980,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(TypeAlias, self, node, label); + post_emit!(TypeAlias, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2840,13 +2988,14 @@ impl Translator<'_> { &mut self, node: &ast::TypeArg, ) -> Option> { + pre_emit!(TypeArg, self, node); let type_repr = node.ty().and_then(|x| self.emit_type(&x)); let label = self.trap.emit(generated::TypeArg { id: TrapId::Star, type_repr, }); self.emit_location(label, node); - emit_detached!(TypeArg, self, node, label); + post_emit!(TypeArg, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2854,6 +3003,7 @@ impl Translator<'_> { &mut self, node: &ast::TypeBound, ) -> Option> { + pre_emit!(TypeBound, self, node); let is_async = node.async_token().is_some(); let is_const = node.const_token().is_some(); let lifetime = node.lifetime().and_then(|x| self.emit_lifetime(&x)); @@ -2870,7 +3020,7 @@ impl Translator<'_> { use_bound_generic_args, }); self.emit_location(label, node); - emit_detached!(TypeBound, self, node, label); + post_emit!(TypeBound, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2878,6 +3028,7 @@ impl Translator<'_> { &mut self, node: &ast::TypeBoundList, ) -> Option> { + pre_emit!(TypeBoundList, self, node); let bounds = node .bounds() .filter_map(|x| self.emit_type_bound(&x)) @@ -2887,7 +3038,7 @@ impl Translator<'_> { bounds, }); self.emit_location(label, node); - emit_detached!(TypeBoundList, self, node, label); + post_emit!(TypeBoundList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2895,6 +3046,7 @@ impl Translator<'_> { &mut self, node: &ast::TypeParam, ) -> Option> { + pre_emit!(TypeParam, self, node); if self.should_be_excluded(node) { return None; } @@ -2912,7 +3064,7 @@ impl Translator<'_> { type_bound_list, }); self.emit_location(label, node); - emit_detached!(TypeParam, self, node, label); + post_emit!(TypeParam, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2920,6 +3072,7 @@ impl Translator<'_> { &mut self, node: &ast::UnderscoreExpr, ) -> Option> { + pre_emit!(UnderscoreExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2929,11 +3082,12 @@ impl Translator<'_> { attrs, }); self.emit_location(label, node); - emit_detached!(UnderscoreExpr, self, node, label); + post_emit!(UnderscoreExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_union(&mut self, node: &ast::Union) -> Option> { + pre_emit!(Union, self, node); if self.should_be_excluded(node) { return None; } @@ -2957,11 +3111,12 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(Union, self, node, label); + post_emit!(Union, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_use(&mut self, node: &ast::Use) -> Option> { + pre_emit!(Use, self, node); if self.should_be_excluded(node) { return None; } @@ -2975,7 +3130,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(Use, self, node, label); + post_emit!(Use, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2983,6 +3138,7 @@ impl Translator<'_> { &mut self, node: &ast::UseBoundGenericArgs, ) -> Option> { + pre_emit!(UseBoundGenericArgs, self, node); let use_bound_generic_args = node .use_bound_generic_args() .filter_map(|x| self.emit_use_bound_generic_arg(&x)) @@ -2992,7 +3148,7 @@ impl Translator<'_> { use_bound_generic_args, }); self.emit_location(label, node); - emit_detached!(UseBoundGenericArgs, self, node, label); + post_emit!(UseBoundGenericArgs, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3000,6 +3156,7 @@ impl Translator<'_> { &mut self, node: &ast::UseTree, ) -> Option> { + pre_emit!(UseTree, self, node); let is_glob = node.star_token().is_some(); let path = node.path().and_then(|x| self.emit_path(&x)); let rename = node.rename().and_then(|x| self.emit_rename(&x)); @@ -3014,7 +3171,7 @@ impl Translator<'_> { use_tree_list, }); self.emit_location(label, node); - emit_detached!(UseTree, self, node, label); + post_emit!(UseTree, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3022,6 +3179,7 @@ impl Translator<'_> { &mut self, node: &ast::UseTreeList, ) -> Option> { + pre_emit!(UseTreeList, self, node); let use_trees = node .use_trees() .filter_map(|x| self.emit_use_tree(&x)) @@ -3031,7 +3189,7 @@ impl Translator<'_> { use_trees, }); self.emit_location(label, node); - emit_detached!(UseTreeList, self, node, label); + post_emit!(UseTreeList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3039,6 +3197,7 @@ impl Translator<'_> { &mut self, node: &ast::Variant, ) -> Option> { + pre_emit!(Variant, self, node); if self.should_be_excluded(node) { return None; } @@ -3056,7 +3215,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(Variant, self, node, label); + post_emit!(Variant, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3064,6 +3223,7 @@ impl Translator<'_> { &mut self, node: &ast::VariantList, ) -> Option> { + pre_emit!(VariantList, self, node); let variants = node .variants() .filter_map(|x| self.emit_variant(&x)) @@ -3073,7 +3233,7 @@ impl Translator<'_> { variants, }); self.emit_location(label, node); - emit_detached!(VariantList, self, node, label); + post_emit!(VariantList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3081,13 +3241,14 @@ impl Translator<'_> { &mut self, node: &ast::Visibility, ) -> Option> { + pre_emit!(Visibility, self, node); let path = node.path().and_then(|x| self.emit_path(&x)); let label = self.trap.emit(generated::Visibility { id: TrapId::Star, path, }); self.emit_location(label, node); - emit_detached!(Visibility, self, node, label); + post_emit!(Visibility, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3095,6 +3256,7 @@ impl Translator<'_> { &mut self, node: &ast::WhereClause, ) -> Option> { + pre_emit!(WhereClause, self, node); let predicates = node .predicates() .filter_map(|x| self.emit_where_pred(&x)) @@ -3104,7 +3266,7 @@ impl Translator<'_> { predicates, }); self.emit_location(label, node); - emit_detached!(WhereClause, self, node, label); + post_emit!(WhereClause, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3112,6 +3274,7 @@ impl Translator<'_> { &mut self, node: &ast::WherePred, ) -> Option> { + pre_emit!(WherePred, self, node); let generic_param_list = node .generic_param_list() .and_then(|x| self.emit_generic_param_list(&x)); @@ -3128,7 +3291,7 @@ impl Translator<'_> { type_bound_list, }); self.emit_location(label, node); - emit_detached!(WherePred, self, node, label); + post_emit!(WherePred, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3136,6 +3299,7 @@ impl Translator<'_> { &mut self, node: &ast::WhileExpr, ) -> Option> { + pre_emit!(WhileExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -3151,7 +3315,7 @@ impl Translator<'_> { loop_body, }); self.emit_location(label, node); - emit_detached!(WhileExpr, self, node, label); + post_emit!(WhileExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3159,9 +3323,10 @@ impl Translator<'_> { &mut self, node: &ast::WildcardPat, ) -> Option> { + pre_emit!(WildcardPat, self, node); let label = self.trap.emit(generated::WildcardPat { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(WildcardPat, self, node, label); + post_emit!(WildcardPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3169,6 +3334,7 @@ impl Translator<'_> { &mut self, node: &ast::YeetExpr, ) -> Option> { + pre_emit!(YeetExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -3180,7 +3346,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(YeetExpr, self, node, label); + post_emit!(YeetExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3188,6 +3354,7 @@ impl Translator<'_> { &mut self, node: &ast::YieldExpr, ) -> Option> { + pre_emit!(YieldExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -3199,7 +3366,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(YieldExpr, self, node, label); + post_emit!(YieldExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } From 31b48e18e62a365a1af5339a7b7d4e80629d611e Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 19 May 2025 11:30:28 +0200 Subject: [PATCH 3/7] Rust: fix `BadCtorInitialization` test --- .../security/CWE-696/BadCtorInitialization.ql | 3 +- .../CWE-696/BadCTorInitialization.expected | 108 +++++++++++------- .../test/query-tests/security/CWE-696/test.rs | 12 +- 3 files changed, 73 insertions(+), 50 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index 75946d89e11b..cff84ed51d70 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -82,4 +82,5 @@ query predicate edges(PathElement pred, PathElement succ) { from CtorAttr source, StdCall sink where edges+(source, sink) select sink, source, sink, - "Call to " + sink.toString() + " in a function with the " + source.getWhichAttr() + " attribute." + "Call to " + sink.toString() + " from the standard library in a function with the " + + source.getWhichAttr() + " attribute." diff --git a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected index 9d8fc2524718..3ac74a3cb13b 100644 --- a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected +++ b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected @@ -1,49 +1,71 @@ #select -| test.rs:30:9:30:25 | ...::stdout(...) | test.rs:28:1:28:13 | Attr | test.rs:30:9:30:25 | ...::stdout(...) | Call to ...::stdout(...) in a function with the ctor attribute. | -| test.rs:35:9:35:25 | ...::stdout(...) | test.rs:33:1:33:13 | Attr | test.rs:35:9:35:25 | ...::stdout(...) | Call to ...::stdout(...) in a function with the dtor attribute. | -| test.rs:42:9:42:25 | ...::stdout(...) | test.rs:39:1:39:13 | Attr | test.rs:42:9:42:25 | ...::stdout(...) | Call to ...::stdout(...) in a function with the dtor attribute. | -| test.rs:52:9:52:16 | stdout(...) | test.rs:50:1:50:7 | Attr | test.rs:52:9:52:16 | stdout(...) | Call to stdout(...) in a function with the ctor attribute. | -| test.rs:57:9:57:16 | stderr(...) | test.rs:55:1:55:7 | Attr | test.rs:57:9:57:16 | stderr(...) | Call to stderr(...) in a function with the ctor attribute. | -| test.rs:62:14:62:28 | ...::_print(...) | test.rs:60:1:60:7 | Attr | test.rs:62:14:62:28 | ...::_print(...) | Call to ...::_print(...) in a function with the ctor attribute. | -| test.rs:68:9:68:24 | ...::stdin(...) | test.rs:65:1:65:7 | Attr | test.rs:68:9:68:24 | ...::stdin(...) | Call to ...::stdin(...) in a function with the ctor attribute. | -| test.rs:89:5:89:35 | ...::sleep(...) | test.rs:87:1:87:7 | Attr | test.rs:89:5:89:35 | ...::sleep(...) | Call to ...::sleep(...) in a function with the ctor attribute. | -| test.rs:96:5:96:23 | ...::exit(...) | test.rs:94:1:94:7 | Attr | test.rs:96:5:96:23 | ...::exit(...) | Call to ...::exit(...) in a function with the ctor attribute. | -| test.rs:125:9:125:16 | stderr(...) | test.rs:128:1:128:7 | Attr | test.rs:125:9:125:16 | stderr(...) | Call to stderr(...) in a function with the ctor attribute. | -| test.rs:125:9:125:16 | stderr(...) | test.rs:144:1:144:7 | Attr | test.rs:125:9:125:16 | stderr(...) | Call to stderr(...) in a function with the ctor attribute. | -| test.rs:125:9:125:16 | stderr(...) | test.rs:150:1:150:7 | Attr | test.rs:125:9:125:16 | stderr(...) | Call to stderr(...) in a function with the ctor attribute. | -| test.rs:125:9:125:44 | ... .write_all(...) | test.rs:128:1:128:7 | Attr | test.rs:125:9:125:44 | ... .write_all(...) | Call to ... .write_all(...) in a function with the ctor attribute. | -| test.rs:125:9:125:44 | ... .write_all(...) | test.rs:144:1:144:7 | Attr | test.rs:125:9:125:44 | ... .write_all(...) | Call to ... .write_all(...) in a function with the ctor attribute. | -| test.rs:125:9:125:44 | ... .write_all(...) | test.rs:150:1:150:7 | Attr | test.rs:125:9:125:44 | ... .write_all(...) | Call to ... .write_all(...) in a function with the ctor attribute. | -| test.rs:170:5:170:15 | ...::stdout(...) | test.rs:168:1:168:7 | Attr | test.rs:170:5:170:15 | ...::stdout(...) | Call to ...::stdout(...) in a function with the ctor attribute. | +| test.rs:30:9:30:24 | ...::stdout(...) | test.rs:28:1:28:13 | Attr | test.rs:30:9:30:24 | ...::stdout(...) | Call to ...::stdout(...) from the standard library in a function with the ctor attribute. | +| test.rs:30:9:30:48 | ... .write(...) | test.rs:28:1:28:13 | Attr | test.rs:30:9:30:48 | ... .write(...) | Call to ... .write(...) from the standard library in a function with the ctor attribute. | +| test.rs:35:9:35:24 | ...::stdout(...) | test.rs:33:1:33:13 | Attr | test.rs:35:9:35:24 | ...::stdout(...) | Call to ...::stdout(...) from the standard library in a function with the dtor attribute. | +| test.rs:35:9:35:48 | ... .write(...) | test.rs:33:1:33:13 | Attr | test.rs:35:9:35:48 | ... .write(...) | Call to ... .write(...) from the standard library in a function with the dtor attribute. | +| test.rs:42:9:42:24 | ...::stdout(...) | test.rs:39:1:39:13 | Attr | test.rs:42:9:42:24 | ...::stdout(...) | Call to ...::stdout(...) from the standard library in a function with the dtor attribute. | +| test.rs:42:9:42:48 | ... .write(...) | test.rs:39:1:39:13 | Attr | test.rs:42:9:42:48 | ... .write(...) | Call to ... .write(...) from the standard library in a function with the dtor attribute. | +| test.rs:52:9:52:15 | stdout(...) | test.rs:50:1:50:7 | Attr | test.rs:52:9:52:15 | stdout(...) | Call to stdout(...) from the standard library in a function with the ctor attribute. | +| test.rs:52:9:52:39 | ... .write(...) | test.rs:50:1:50:7 | Attr | test.rs:52:9:52:39 | ... .write(...) | Call to ... .write(...) from the standard library in a function with the ctor attribute. | +| test.rs:57:9:57:15 | stderr(...) | test.rs:55:1:55:7 | Attr | test.rs:57:9:57:15 | stderr(...) | Call to stderr(...) from the standard library in a function with the ctor attribute. | +| test.rs:57:9:57:43 | ... .write_all(...) | test.rs:55:1:55:7 | Attr | test.rs:57:9:57:43 | ... .write_all(...) | Call to ... .write_all(...) from the standard library in a function with the ctor attribute. | +| test.rs:62:14:62:28 | ...::_print(...) | test.rs:60:1:60:7 | Attr | test.rs:62:14:62:28 | ...::_print(...) | Call to ...::_print(...) from the standard library in a function with the ctor attribute. | +| test.rs:68:9:68:23 | ...::stdin(...) | test.rs:65:1:65:7 | Attr | test.rs:68:9:68:23 | ...::stdin(...) | Call to ...::stdin(...) from the standard library in a function with the ctor attribute. | +| test.rs:68:9:68:44 | ... .read_line(...) | test.rs:65:1:65:7 | Attr | test.rs:68:9:68:44 | ... .read_line(...) | Call to ... .read_line(...) from the standard library in a function with the ctor attribute. | +| test.rs:75:17:75:44 | ...::create(...) | test.rs:73:1:73:7 | Attr | test.rs:75:17:75:44 | ...::create(...) | Call to ...::create(...) from the standard library in a function with the ctor attribute. | +| test.rs:80:14:80:37 | ...::now(...) | test.rs:78:1:78:7 | Attr | test.rs:80:14:80:37 | ...::now(...) | Call to ...::now(...) from the standard library in a function with the ctor attribute. | +| test.rs:89:5:89:34 | ...::sleep(...) | test.rs:87:1:87:7 | Attr | test.rs:89:5:89:34 | ...::sleep(...) | Call to ...::sleep(...) from the standard library in a function with the ctor attribute. | +| test.rs:96:5:96:22 | ...::exit(...) | test.rs:94:1:94:7 | Attr | test.rs:96:5:96:22 | ...::exit(...) | Call to ...::exit(...) from the standard library in a function with the ctor attribute. | +| test.rs:125:9:125:16 | stderr(...) | test.rs:128:1:128:7 | Attr | test.rs:125:9:125:16 | stderr(...) | Call to stderr(...) from the standard library in a function with the ctor attribute. | +| test.rs:125:9:125:16 | stderr(...) | test.rs:144:1:144:7 | Attr | test.rs:125:9:125:16 | stderr(...) | Call to stderr(...) from the standard library in a function with the ctor attribute. | +| test.rs:125:9:125:16 | stderr(...) | test.rs:150:1:150:7 | Attr | test.rs:125:9:125:16 | stderr(...) | Call to stderr(...) from the standard library in a function with the ctor attribute. | +| test.rs:125:9:125:44 | ... .write_all(...) | test.rs:128:1:128:7 | Attr | test.rs:125:9:125:44 | ... .write_all(...) | Call to ... .write_all(...) from the standard library in a function with the ctor attribute. | +| test.rs:125:9:125:44 | ... .write_all(...) | test.rs:144:1:144:7 | Attr | test.rs:125:9:125:44 | ... .write_all(...) | Call to ... .write_all(...) from the standard library in a function with the ctor attribute. | +| test.rs:125:9:125:44 | ... .write_all(...) | test.rs:150:1:150:7 | Attr | test.rs:125:9:125:44 | ... .write_all(...) | Call to ... .write_all(...) from the standard library in a function with the ctor attribute. | +| test.rs:168:1:168:7 | ... .write(...) | test.rs:168:1:168:7 | Attr | test.rs:168:1:168:7 | ... .write(...) | Call to ... .write(...) from the standard library in a function with the ctor attribute. | +| test.rs:168:1:168:7 | ...::stdout(...) | test.rs:168:1:168:7 | Attr | test.rs:168:1:168:7 | ...::stdout(...) | Call to ...::stdout(...) from the standard library in a function with the ctor attribute. | edges -| test.rs:28:1:28:13 | Attr | test.rs:28:1:31:1 | fn bad1_1 | -| test.rs:28:1:31:1 | fn bad1_1 | test.rs:30:9:30:25 | ...::stdout(...) | -| test.rs:33:1:33:13 | Attr | test.rs:33:1:36:1 | fn bad1_2 | -| test.rs:33:1:36:1 | fn bad1_2 | test.rs:35:9:35:25 | ...::stdout(...) | -| test.rs:38:1:43:1 | fn bad1_3 | test.rs:42:9:42:25 | ...::stdout(...) | -| test.rs:39:1:39:13 | Attr | test.rs:38:1:43:1 | fn bad1_3 | -| test.rs:50:1:50:7 | Attr | test.rs:50:1:53:1 | fn bad2_1 | -| test.rs:50:1:53:1 | fn bad2_1 | test.rs:52:9:52:16 | stdout(...) | -| test.rs:55:1:55:7 | Attr | test.rs:55:1:58:1 | fn bad2_2 | -| test.rs:55:1:58:1 | fn bad2_2 | test.rs:57:9:57:16 | stderr(...) | -| test.rs:60:1:60:7 | Attr | test.rs:60:1:63:1 | fn bad2_3 | -| test.rs:60:1:63:1 | fn bad2_3 | test.rs:62:14:62:28 | ...::_print(...) | -| test.rs:65:1:65:7 | Attr | test.rs:65:1:69:1 | fn bad2_4 | -| test.rs:65:1:69:1 | fn bad2_4 | test.rs:68:9:68:24 | ...::stdin(...) | -| test.rs:87:1:87:7 | Attr | test.rs:87:1:90:1 | fn bad2_7 | -| test.rs:87:1:90:1 | fn bad2_7 | test.rs:89:5:89:35 | ...::sleep(...) | -| test.rs:94:1:94:7 | Attr | test.rs:94:1:97:1 | fn bad2_8 | -| test.rs:94:1:97:1 | fn bad2_8 | test.rs:96:5:96:23 | ...::exit(...) | +| test.rs:28:1:28:13 | Attr | test.rs:29:4:30:50 | fn bad1_1 | +| test.rs:29:4:30:50 | fn bad1_1 | test.rs:30:9:30:24 | ...::stdout(...) | +| test.rs:29:4:30:50 | fn bad1_1 | test.rs:30:9:30:48 | ... .write(...) | +| test.rs:33:1:33:13 | Attr | test.rs:34:4:35:50 | fn bad1_2 | +| test.rs:34:4:35:50 | fn bad1_2 | test.rs:35:9:35:24 | ...::stdout(...) | +| test.rs:34:4:35:50 | fn bad1_2 | test.rs:35:9:35:48 | ... .write(...) | +| test.rs:38:1:42:50 | fn bad1_3 | test.rs:42:9:42:24 | ...::stdout(...) | +| test.rs:38:1:42:50 | fn bad1_3 | test.rs:42:9:42:48 | ... .write(...) | +| test.rs:39:1:39:13 | Attr | test.rs:38:1:42:50 | fn bad1_3 | +| test.rs:50:1:50:7 | Attr | test.rs:51:4:52:41 | fn bad2_1 | +| test.rs:51:4:52:41 | fn bad2_1 | test.rs:52:9:52:15 | stdout(...) | +| test.rs:51:4:52:41 | fn bad2_1 | test.rs:52:9:52:39 | ... .write(...) | +| test.rs:55:1:55:7 | Attr | test.rs:56:4:57:45 | fn bad2_2 | +| test.rs:56:4:57:45 | fn bad2_2 | test.rs:57:9:57:15 | stderr(...) | +| test.rs:56:4:57:45 | fn bad2_2 | test.rs:57:9:57:43 | ... .write_all(...) | +| test.rs:60:1:60:7 | Attr | test.rs:61:4:62:30 | fn bad2_3 | +| test.rs:61:4:62:30 | fn bad2_3 | test.rs:62:14:62:28 | ...::_print(...) | +| test.rs:65:1:65:7 | Attr | test.rs:66:4:68:46 | fn bad2_4 | +| test.rs:66:4:68:46 | fn bad2_4 | test.rs:68:9:68:23 | ...::stdin(...) | +| test.rs:66:4:68:46 | fn bad2_4 | test.rs:68:9:68:44 | ... .read_line(...) | +| test.rs:73:1:73:7 | Attr | test.rs:74:4:75:55 | fn bad2_5 | +| test.rs:74:4:75:55 | fn bad2_5 | test.rs:75:17:75:44 | ...::create(...) | +| test.rs:78:1:78:7 | Attr | test.rs:79:4:80:39 | fn bad2_6 | +| test.rs:79:4:80:39 | fn bad2_6 | test.rs:80:14:80:37 | ...::now(...) | +| test.rs:87:1:87:7 | Attr | test.rs:88:4:89:36 | fn bad2_7 | +| test.rs:88:4:89:36 | fn bad2_7 | test.rs:89:5:89:34 | ...::sleep(...) | +| test.rs:94:1:94:7 | Attr | test.rs:95:4:96:24 | fn bad2_8 | +| test.rs:95:4:96:24 | fn bad2_8 | test.rs:96:5:96:22 | ...::exit(...) | | test.rs:124:1:126:1 | fn call_target3_1 | test.rs:125:9:125:16 | stderr(...) | | test.rs:124:1:126:1 | fn call_target3_1 | test.rs:125:9:125:44 | ... .write_all(...) | -| test.rs:128:1:128:7 | Attr | test.rs:128:1:131:1 | fn bad3_1 | -| test.rs:128:1:131:1 | fn bad3_1 | test.rs:130:5:130:20 | call_target3_1(...) | -| test.rs:130:5:130:20 | call_target3_1(...) | test.rs:124:1:126:1 | fn call_target3_1 | -| test.rs:144:1:144:7 | Attr | test.rs:144:1:148:1 | fn bad3_3 | +| test.rs:128:1:128:7 | Attr | test.rs:129:4:130:21 | fn bad3_1 | +| test.rs:129:4:130:21 | fn bad3_1 | test.rs:130:5:130:19 | call_target3_1(...) | +| test.rs:130:5:130:19 | call_target3_1(...) | test.rs:124:1:126:1 | fn call_target3_1 | +| test.rs:144:1:144:7 | Attr | test.rs:145:4:147:21 | fn bad3_3 | | test.rs:144:1:148:1 | fn bad3_3 | test.rs:146:5:146:20 | call_target3_1(...) | +| test.rs:145:4:147:21 | fn bad3_3 | test.rs:146:5:146:19 | call_target3_1(...) | +| test.rs:146:5:146:19 | call_target3_1(...) | test.rs:124:1:126:1 | fn call_target3_1 | | test.rs:146:5:146:20 | call_target3_1(...) | test.rs:124:1:126:1 | fn call_target3_1 | -| test.rs:150:1:150:7 | Attr | test.rs:150:1:153:1 | fn bad3_4 | -| test.rs:150:1:153:1 | fn bad3_4 | test.rs:152:5:152:12 | bad3_3(...) | -| test.rs:152:5:152:12 | bad3_3(...) | test.rs:144:1:148:1 | fn bad3_3 | -| test.rs:168:1:168:7 | Attr | test.rs:168:1:171:1 | fn bad4_1 | -| test.rs:168:1:171:1 | fn bad4_1 | test.rs:170:5:170:15 | ...::stdout(...) | +| test.rs:150:1:150:7 | Attr | test.rs:151:4:152:13 | fn bad3_4 | +| test.rs:151:4:152:13 | fn bad3_4 | test.rs:152:5:152:11 | bad3_3(...) | +| test.rs:152:5:152:11 | bad3_3(...) | test.rs:144:1:148:1 | fn bad3_3 | +| test.rs:168:1:168:7 | Attr | test.rs:169:4:170:16 | fn bad4_1 | +| test.rs:169:4:170:16 | fn bad4_1 | test.rs:168:1:168:7 | ... .write(...) | +| test.rs:169:4:170:16 | fn bad4_1 | test.rs:168:1:168:7 | ...::stdout(...) | diff --git a/rust/ql/test/query-tests/security/CWE-696/test.rs b/rust/ql/test/query-tests/security/CWE-696/test.rs index b23c06aa6a69..f589994d5d1d 100644 --- a/rust/ql/test/query-tests/security/CWE-696/test.rs +++ b/rust/ql/test/query-tests/security/CWE-696/test.rs @@ -70,14 +70,14 @@ fn bad2_4() { use std::fs; -#[ctor] // $ MISSING: Source=source2_5 +#[ctor] // $ Source=source2_5 fn bad2_5() { - let _buff = fs::File::create("hello.txt").unwrap(); // $ MISSING: Alert[rust/ctor-initialization]=source2_5 + let _buff = fs::File::create("hello.txt").unwrap(); // $ Alert[rust/ctor-initialization]=source2_5 } -#[ctor] // $ MISSING: Source=source2_6 +#[ctor] // $ Source=source2_6 fn bad2_6() { - let _t = std::time::Instant::now(); // $ MISSING: Alert[rust/ctor-initialization]=source2_6 + let _t = std::time::Instant::now(); // $ Alert[rust/ctor-initialization]=source2_6 } use std::time::Duration; @@ -165,7 +165,7 @@ macro_rules! macro4_1 { }; } -#[ctor] // $ Source=source4_1 +#[ctor] // $ Alert[rust/ctor-initialization] fn bad4_1() { - macro4_1!(); // $ Alert[rust/ctor-initialization]=source4_1 + macro4_1!(); } From 5183d1610f81138638541bfff08afbeef6d87f23 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 19 May 2025 13:56:28 +0200 Subject: [PATCH 4/7] Rust: enhance macro expansion integration test --- .../macro-expansion/src/lib.rs | 7 ++++- .../macro-expansion/summary.expected | 16 +++++++++++ .../macro-expansion/summary.qlref | 1 + .../macro-expansion/test.expected | 28 +++++++++++-------- 4 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 rust/ql/integration-tests/macro-expansion/summary.expected create mode 100644 rust/ql/integration-tests/macro-expansion/summary.qlref diff --git a/rust/ql/integration-tests/macro-expansion/src/lib.rs b/rust/ql/integration-tests/macro-expansion/src/lib.rs index 6d2d6037e5d2..2007d3b111aa 100644 --- a/rust/ql/integration-tests/macro-expansion/src/lib.rs +++ b/rust/ql/integration-tests/macro-expansion/src/lib.rs @@ -1,7 +1,12 @@ use macros::repeat; #[repeat(3)] -fn foo() {} +fn foo() { + println!("Hello, world!"); + + #[repeat(2)] + fn inner() {} +} #[repeat(2)] #[repeat(3)] diff --git a/rust/ql/integration-tests/macro-expansion/summary.expected b/rust/ql/integration-tests/macro-expansion/summary.expected new file mode 100644 index 000000000000..529d1736d028 --- /dev/null +++ b/rust/ql/integration-tests/macro-expansion/summary.expected @@ -0,0 +1,16 @@ +| Extraction errors | 0 | +| Extraction warnings | 0 | +| Files extracted - total | 2 | +| Files extracted - with errors | 0 | +| Files extracted - without errors | 2 | +| Files extracted - without errors % | 100 | +| Inconsistencies - AST | 0 | +| Inconsistencies - CFG | 0 | +| Inconsistencies - Path resolution | 0 | +| Inconsistencies - SSA | 0 | +| Inconsistencies - data flow | 0 | +| Lines of code extracted | 46 | +| Lines of user code extracted | 29 | +| Macro calls - resolved | 52 | +| Macro calls - total | 53 | +| Macro calls - unresolved | 1 | diff --git a/rust/ql/integration-tests/macro-expansion/summary.qlref b/rust/ql/integration-tests/macro-expansion/summary.qlref new file mode 100644 index 000000000000..926fc7903911 --- /dev/null +++ b/rust/ql/integration-tests/macro-expansion/summary.qlref @@ -0,0 +1 @@ +queries/summary/SummaryStatsReduced.ql diff --git a/rust/ql/integration-tests/macro-expansion/test.expected b/rust/ql/integration-tests/macro-expansion/test.expected index 1247930bd226..83edecf5d5df 100644 --- a/rust/ql/integration-tests/macro-expansion/test.expected +++ b/rust/ql/integration-tests/macro-expansion/test.expected @@ -1,11 +1,17 @@ -| src/lib.rs:3:1:4:11 | fn foo | 0 | src/lib.rs:4:1:4:10 | fn foo_0 | -| src/lib.rs:3:1:4:11 | fn foo | 1 | src/lib.rs:4:1:4:10 | fn foo_1 | -| src/lib.rs:3:1:4:11 | fn foo | 2 | src/lib.rs:4:1:4:10 | fn foo_2 | -| src/lib.rs:6:1:8:11 | fn bar | 0 | src/lib.rs:7:1:8:10 | fn bar_0 | -| src/lib.rs:6:1:8:11 | fn bar | 1 | src/lib.rs:7:1:8:10 | fn bar_1 | -| src/lib.rs:7:1:8:10 | fn bar_0 | 0 | src/lib.rs:8:1:8:10 | fn bar_0_0 | -| src/lib.rs:7:1:8:10 | fn bar_0 | 1 | src/lib.rs:8:1:8:10 | fn bar_0_1 | -| src/lib.rs:7:1:8:10 | fn bar_0 | 2 | src/lib.rs:8:1:8:10 | fn bar_0_2 | -| src/lib.rs:7:1:8:10 | fn bar_1 | 0 | src/lib.rs:8:1:8:10 | fn bar_1_0 | -| src/lib.rs:7:1:8:10 | fn bar_1 | 1 | src/lib.rs:8:1:8:10 | fn bar_1_1 | -| src/lib.rs:7:1:8:10 | fn bar_1 | 2 | src/lib.rs:8:1:8:10 | fn bar_1_2 | +| src/lib.rs:3:1:9:1 | fn foo | 0 | src/lib.rs:4:1:8:16 | fn foo_0 | +| src/lib.rs:3:1:9:1 | fn foo | 1 | src/lib.rs:4:1:8:16 | fn foo_1 | +| src/lib.rs:3:1:9:1 | fn foo | 2 | src/lib.rs:4:1:8:16 | fn foo_2 | +| src/lib.rs:7:5:8:16 | fn inner | 0 | src/lib.rs:8:5:8:16 | fn inner_0 | +| src/lib.rs:7:5:8:16 | fn inner | 0 | src/lib.rs:8:5:8:16 | fn inner_0 | +| src/lib.rs:7:5:8:16 | fn inner | 0 | src/lib.rs:8:5:8:16 | fn inner_0 | +| src/lib.rs:7:5:8:16 | fn inner | 1 | src/lib.rs:8:5:8:16 | fn inner_1 | +| src/lib.rs:7:5:8:16 | fn inner | 1 | src/lib.rs:8:5:8:16 | fn inner_1 | +| src/lib.rs:7:5:8:16 | fn inner | 1 | src/lib.rs:8:5:8:16 | fn inner_1 | +| src/lib.rs:11:1:13:11 | fn bar | 0 | src/lib.rs:12:1:13:10 | fn bar_0 | +| src/lib.rs:11:1:13:11 | fn bar | 1 | src/lib.rs:12:1:13:10 | fn bar_1 | +| src/lib.rs:12:1:13:10 | fn bar_0 | 0 | src/lib.rs:13:1:13:10 | fn bar_0_0 | +| src/lib.rs:12:1:13:10 | fn bar_0 | 1 | src/lib.rs:13:1:13:10 | fn bar_0_1 | +| src/lib.rs:12:1:13:10 | fn bar_0 | 2 | src/lib.rs:13:1:13:10 | fn bar_0_2 | +| src/lib.rs:12:1:13:10 | fn bar_1 | 0 | src/lib.rs:13:1:13:10 | fn bar_1_0 | +| src/lib.rs:12:1:13:10 | fn bar_1 | 1 | src/lib.rs:13:1:13:10 | fn bar_1_1 | +| src/lib.rs:12:1:13:10 | fn bar_1 | 2 | src/lib.rs:13:1:13:10 | fn bar_1_2 | From 01e22b72668f17b2e4325481bf3cde0e77a16c3a Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 22 May 2025 11:47:33 +0200 Subject: [PATCH 5/7] Rust: remove wrong comment --- rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index cff84ed51d70..80e1043a979c 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -55,7 +55,6 @@ predicate edgesFwd(PathElement pred, PathElement succ) { ) ) or - // callable -> callable attribute macro expansion // [forwards reachable] callable -> enclosed call edgesFwd(_, pred) and pred = succ.(CallExprBase).getEnclosingCallable() From 5c294617c5096066c4ebc2bf575a5e61ea6f13f9 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 23 May 2025 14:43:18 +0200 Subject: [PATCH 6/7] Rust: update a comment --- rust/extractor/src/translate/base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/extractor/src/translate/base.rs b/rust/extractor/src/translate/base.rs index d1cec34242c9..a2f3101b75e7 100644 --- a/rust/extractor/src/translate/base.rs +++ b/rust/extractor/src/translate/base.rs @@ -333,7 +333,7 @@ impl<'a> Translator<'a> { ) { if self.macro_context_depth > 0 { // we are in an attribute macro, don't emit anything: we would be failing to expand any - // way as rust-analyser now only expands in the context of an expansion + // way as from version 0.0.274 rust-analyser only expands in the context of an expansion return; } if let Some(expanded) = self From a749cf934ae87caf773a10e386ca4b45605b1ad2 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 26 May 2025 14:15:56 +0200 Subject: [PATCH 7/7] Rust: accept test changes --- rust/ql/integration-tests/macro-expansion/summary.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/integration-tests/macro-expansion/summary.expected b/rust/ql/integration-tests/macro-expansion/summary.expected index 529d1736d028..6917d67b1cf0 100644 --- a/rust/ql/integration-tests/macro-expansion/summary.expected +++ b/rust/ql/integration-tests/macro-expansion/summary.expected @@ -9,7 +9,7 @@ | Inconsistencies - Path resolution | 0 | | Inconsistencies - SSA | 0 | | Inconsistencies - data flow | 0 | -| Lines of code extracted | 46 | +| Lines of code extracted | 29 | | Lines of user code extracted | 29 | | Macro calls - resolved | 52 | | Macro calls - total | 53 |