Merge pull request #19572 from github/redsun82/rust-macro

Rust: turn off macro expansion in code to be expanded by attribute macros
This commit is contained in:
Paolo Tranquilli
2025-05-27 08:29:20 +02:00
committed by GitHub
10 changed files with 506 additions and 243 deletions

View File

@@ -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<Label<generated::{{name}}>> {
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<Label<generated::{{name}}>> {
pre_emit!({{name}}, self, node);
if self.should_be_excluded(node) { return None; }
{{#has_attrs}}
if self.should_be_excluded_attrs(node) { return None; }
@@ -59,7 +61,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)
}

View File

@@ -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);
};
@@ -106,8 +114,9 @@ pub struct Translator<'a> {
line_index: LineIndex,
file_id: Option<EditionedFileId>,
pub semantics: Option<&'a Semantics<'a, RootDatabase>>,
resolve_paths: ResolvePaths,
resolve_paths: bool,
source_kind: SourceKind,
macro_context_depth: usize,
}
const UNKNOWN_LOCATION: (LineCol, LineCol) =
@@ -130,8 +139,9 @@ 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,
source_kind,
macro_context_depth: 0,
}
}
fn location(&self, range: TextRange) -> Option<(LineCol, LineCol)> {
@@ -337,6 +347,11 @@ impl<'a> Translator<'a> {
mcall: &ast::MacroCall,
label: Label<generated::MacroCall>,
) {
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 from version 0.0.274 rust-analyser only expands in the context of an expansion
return;
}
if let Some(expanded) = self
.semantics
.as_ref()
@@ -537,7 +552,7 @@ impl<'a> Translator<'a> {
item: &T,
label: Label<generated::Addressable>,
) {
if self.resolve_paths == ResolvePaths::No {
if !self.resolve_paths {
return;
}
(|| {
@@ -560,7 +575,7 @@ impl<'a> Translator<'a> {
item: &ast::Variant,
label: Label<generated::Variant>,
) {
if self.resolve_paths == ResolvePaths::No {
if !self.resolve_paths {
return;
}
(|| {
@@ -583,7 +598,7 @@ impl<'a> Translator<'a> {
item: &impl PathAst,
label: Label<generated::Resolvable>,
) {
if self.resolve_paths == ResolvePaths::No {
if !self.resolve_paths {
return;
}
(|| {
@@ -606,7 +621,7 @@ impl<'a> Translator<'a> {
item: &ast::MethodCallExpr,
label: Label<generated::MethodCallExpr>,
) {
if self.resolve_paths == ResolvePaths::No {
if !self.resolve_paths {
return;
}
(|| {
@@ -708,6 +723,16 @@ 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<generated::Item>) {
// TODO: remove this after fixing exponential expansion on libraries like funty-2.0.0
if self.source_kind == SourceKind::Library {
@@ -715,6 +740,16 @@ impl<'a> Translator<'a> {
}
(|| {
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)?;

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,12 @@
use macros::repeat;
#[repeat(3)]
fn foo() {}
fn foo() {
println!("Hello, world!");
#[repeat(2)]
fn inner() {}
}
#[repeat(2)]
#[repeat(3)]

View File

@@ -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 | 29 |
| Lines of user code extracted | 29 |
| Macro calls - resolved | 52 |
| Macro calls - total | 53 |
| Macro calls - unresolved | 1 |

View File

@@ -0,0 +1 @@
queries/summary/SummaryStatsReduced.ql

View File

@@ -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 |

View File

@@ -44,8 +44,16 @@ 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
// [forwards reachable] callable -> enclosed call
edgesFwd(_, pred) and
@@ -73,4 +81,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."

View File

@@ -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(...) |

View File

@@ -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!();
}