Merge branch 'main' into redsun82/rust-derive-macro-expansion

This commit is contained in:
Arthur Baars
2025-06-20 19:27:15 +02:00
31 changed files with 558 additions and 170 deletions

View File

@@ -39,6 +39,8 @@ import java.util.stream.Stream;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import com.semmle.js.extractor.tsconfig.TsConfigJson;
import com.semmle.js.extractor.tsconfig.CompilerOptions;
import com.semmle.js.dependencies.AsyncFetcher;
import com.semmle.js.dependencies.DependencyResolver;
import com.semmle.js.dependencies.packument.PackageJson;
@@ -745,6 +747,26 @@ public class AutoBuild {
.filter(p -> !isFileTooLarge(p))
.sorted(PATH_ORDERING)
.collect(Collectors.toCollection(() -> new LinkedHashSet<>()));
// gather all output directories specified in tsconfig.json files
final List<Path> outDirs = new ArrayList<>();
for (Path cfg : tsconfigFiles) {
try {
String txt = new WholeIO().read(cfg);
TsConfigJson root = new Gson().fromJson(txt, TsConfigJson.class);
if (root != null && root.getCompilerOptions() != null) {
if (root.getCompilerOptions().getOutDir() == null) {
// no outDir specified, so skip this tsconfig.json
continue;
}
Path odir = cfg.getParent().resolve(root.getCompilerOptions().getOutDir()).toAbsolutePath().normalize();
outDirs.add(odir);
}
} catch (Exception e) {
// ignore malformed tsconfig or missing fields
}
}
// exclude files in output directories as configured in tsconfig.json
filesToExtract.removeIf(f -> outDirs.stream().anyMatch(od -> f.startsWith(od)));
DependencyInstallationResult dependencyInstallationResult = DependencyInstallationResult.empty;
if (!tsconfigFiles.isEmpty()) {
@@ -796,9 +818,19 @@ public class AutoBuild {
*/
private boolean isFileDerivedFromTypeScriptFile(Path path, Set<Path> extractedFiles) {
String name = path.getFileName().toString();
if (!name.endsWith(".js"))
// only skip JS variants when a corresponding TS/TSX file was already extracted
if (!(name.endsWith(".js")
|| name.endsWith(".cjs")
|| name.endsWith(".mjs")
|| name.endsWith(".jsx")
|| name.endsWith(".cjsx")
|| name.endsWith(".mjsx"))) {
return false;
String stem = name.substring(0, name.length() - ".js".length());
}
// strip off extension
int dot = name.lastIndexOf('.');
String stem = dot != -1 ? name.substring(0, dot) : name;
// if a TS/TSX file with same base name was extracted, skip this file
for (String ext : FileType.TYPESCRIPT.getExtensions()) {
if (extractedFiles.contains(path.getParent().resolve(stem + ext))) {
return true;
@@ -1154,7 +1186,7 @@ protected DependencyInstallationResult preparePackagesAndDependencies(Set<Path>
}
// extract TypeScript projects from 'tsconfig.json'
if (typeScriptMode == TypeScriptMode.FULL
if (typeScriptMode != TypeScriptMode.NONE
&& treatAsTSConfig(file.getFileName().toString())
&& !excludes.contains(file)
&& isFileIncluded(file)) {

View File

@@ -0,0 +1,13 @@
package com.semmle.js.extractor.tsconfig;
public class CompilerOptions {
private String outDir;
public String getOutDir() {
return outDir;
}
public void setOutDir(String outDir) {
this.outDir = outDir;
}
}

View File

@@ -0,0 +1,13 @@
package com.semmle.js.extractor.tsconfig;
public class TsConfigJson {
private CompilerOptions compilerOptions;
public CompilerOptions getCompilerOptions() {
return compilerOptions;
}
public void setCompilerOptions(CompilerOptions compilerOptions) {
this.compilerOptions = compilerOptions;
}
}

View File

@@ -135,6 +135,7 @@ public class AutoBuildTests {
FileExtractors extractors) {
for (Path f : files) {
actual.add(f.toString());
extractedFiles.add(f);
}
}
@@ -175,7 +176,7 @@ public class AutoBuildTests {
@Test
public void basicTest() throws IOException {
addFile(true, LGTM_SRC, "tst.js");
addFile(false, LGTM_SRC, "tst.js");
addFile(true, LGTM_SRC, "tst.ts");
addFile(true, LGTM_SRC, "tst.html");
addFile(true, LGTM_SRC, "tst.xsjs");
@@ -203,6 +204,43 @@ public class AutoBuildTests {
runTest();
}
@Test
public void skipJsFilesDerivedFromTypeScriptFiles() throws IOException {
// JS-derived files (.js, .cjs, .mjs, .jsx, .cjsx, .mjsx) should be skipped when TS indexing
envVars.put("LGTM_INDEX_TYPESCRIPT", "basic");
// Add TypeScript sources
addFile(true, LGTM_SRC, "foo.ts");
addFile(true, LGTM_SRC, "bar.tsx");
// Add derived JS variants (should be skipped)
addFile(false, LGTM_SRC, "foo.js");
addFile(false, LGTM_SRC, "bar.jsx");
addFile(false, LGTM_SRC, "foo.cjs");
addFile(false, LGTM_SRC, "foo.mjs");
addFile(false, LGTM_SRC, "bar.cjsx");
addFile(false, LGTM_SRC, "bar.mjsx");
// A normal JS file without TS counterpart should be extracted
addFile(true, LGTM_SRC, "normal.js");
runTest();
}
@Test
public void skipFilesInTsconfigOutDir() throws IOException {
envVars.put("LGTM_INDEX_TYPESCRIPT", "basic");
// Files under outDir in tsconfig.json should be excluded
// Create tsconfig.json with outDir set to "dist"
addFile(true, LGTM_SRC, "tsconfig.json");
Path config = Paths.get(LGTM_SRC.toString(), "tsconfig.json");
Files.write(config,
"{\"compilerOptions\":{\"outDir\":\"dist\"}}".getBytes(StandardCharsets.UTF_8));
// Add files outside outDir (should be extracted)
addFile(true, LGTM_SRC, "src", "app.ts");
addFile(true, LGTM_SRC, "main.js");
// Add files under dist/outDir (should be skipped)
addFile(false, LGTM_SRC, "dist", "generated.js");
addFile(false, LGTM_SRC, "dist", "sub", "x.js");
runTest();
}
@Test
public void includeFile() throws IOException {
envVars.put("LGTM_INDEX_INCLUDE", "tst.js");

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The JavaScript extractor now skips generated JavaScript files if the original TypeScript files are already present. It also skips any files in the output directory specified in the `compilerOptions` part of the `tsconfig.json` file.

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Improved data flow tracking through middleware to handle default value and similar patterns.
* Added `req._parsedUrl` as a remote input source.

View File

@@ -925,7 +925,7 @@ module Routing {
private DataFlow::Node getAnAccessPathRhs(Node base, int n, string path) {
// Assigned in the body of a route handler function, which is a middleware
exists(RouteHandler handler | base = handler |
result = AccessPath::getAnAssignmentTo(handler.getParameter(n).ref(), path) and
result = AccessPath::getAnAssignmentTo(handler.getParameter(n).ref(), path).getALocalSource() and
(
exists(handler.getAContinuationInvocation())
or

View File

@@ -618,9 +618,9 @@ module Express {
kind = "body" and
this = ref.getAPropertyRead("body")
or
// `req.path`
// `req.path` and `req._parsedUrl`
kind = "url" and
this = ref.getAPropertyRead("path")
this = ref.getAPropertyRead(["path", "_parsedUrl"])
)
}

View File

@@ -6,6 +6,10 @@
| apollo.serverSide.ts:8:39:8:64 | get(fil ... => {}) | apollo.serverSide.ts:7:36:7:44 | { files } | apollo.serverSide.ts:8:43:8:50 | file.url | The $@ of this request depends on a $@. | apollo.serverSide.ts:8:43:8:50 | file.url | URL | apollo.serverSide.ts:7:36:7:44 | { files } | user-provided value |
| apollo.serverSide.ts:18:37:18:62 | get(fil ... => {}) | apollo.serverSide.ts:17:34:17:42 | { files } | apollo.serverSide.ts:18:41:18:48 | file.url | The $@ of this request depends on a $@. | apollo.serverSide.ts:18:41:18:48 | file.url | URL | apollo.serverSide.ts:17:34:17:42 | { files } | user-provided value |
| axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | axiosInterceptors.serverSide.js:19:21:19:28 | req.body | axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | The $@ of this request depends on a $@. | axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | endpoint | axiosInterceptors.serverSide.js:19:21:19:28 | req.body | user-provided value |
| serverSide2.js:17:28:17:47 | axios.get(targetUrl) | serverSide2.js:10:25:10:31 | req.url | serverSide2.js:17:38:17:46 | targetUrl | The $@ of this request depends on a $@. | serverSide2.js:17:38:17:46 | targetUrl | URL | serverSide2.js:10:25:10:31 | req.url | user-provided value |
| serverSide2.js:20:29:20:49 | axios.g ... etUrl1) | serverSide2.js:9:43:9:56 | req._parsedUrl | serverSide2.js:20:39:20:48 | targetUrl1 | The $@ of this request depends on a $@. | serverSide2.js:20:39:20:48 | targetUrl1 | URL | serverSide2.js:9:43:9:56 | req._parsedUrl | user-provided value |
| serverSide2.js:23:29:23:49 | axios.g ... etUrl2) | serverSide2.js:22:24:22:30 | req.url | serverSide2.js:23:39:23:48 | targetUrl2 | The $@ of this request depends on a $@. | serverSide2.js:23:39:23:48 | targetUrl2 | URL | serverSide2.js:22:24:22:30 | req.url | user-provided value |
| serverSide2.js:26:29:26:49 | axios.g ... etUrl3) | serverSide2.js:11:24:11:30 | req.url | serverSide2.js:26:39:26:48 | targetUrl3 | The $@ of this request depends on a $@. | serverSide2.js:26:39:26:48 | targetUrl3 | URL | serverSide2.js:11:24:11:30 | req.url | user-provided value |
| serverSide.js:18:5:18:20 | request(tainted) | serverSide.js:14:29:14:35 | req.url | serverSide.js:18:13:18:19 | tainted | The $@ of this request depends on a $@. | serverSide.js:18:13:18:19 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value |
| serverSide.js:20:5:20:24 | request.get(tainted) | serverSide.js:14:29:14:35 | req.url | serverSide.js:20:17:20:23 | tainted | The $@ of this request depends on a $@. | serverSide.js:20:17:20:23 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value |
| serverSide.js:24:5:24:20 | request(options) | serverSide.js:14:29:14:35 | req.url | serverSide.js:23:19:23:25 | tainted | The $@ of this request depends on a $@. | serverSide.js:23:19:23:25 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value |
@@ -63,6 +67,18 @@ edges
| axiosInterceptors.serverSide.js:19:21:19:28 | req.body | axiosInterceptors.serverSide.js:19:11:19:17 | { url } | provenance | |
| axiosInterceptors.serverSide.js:20:5:20:25 | userProvidedUrl | axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | provenance | |
| axiosInterceptors.serverSide.js:20:23:20:25 | url | axiosInterceptors.serverSide.js:20:5:20:25 | userProvidedUrl | provenance | |
| serverSide2.js:9:34:9:63 | qs.pars ... .query) | serverSide2.js:19:24:19:51 | req.par ... rsedUrl | provenance | |
| serverSide2.js:9:43:9:56 | req._parsedUrl | serverSide2.js:9:34:9:63 | qs.pars ... .query) | provenance | |
| serverSide2.js:10:25:10:31 | req.url | serverSide2.js:16:23:16:41 | req.parsedQuery.url | provenance | |
| serverSide2.js:11:24:11:30 | req.url | serverSide2.js:25:24:25:41 | req.SomeObject.url | provenance | |
| serverSide2.js:16:11:16:41 | targetUrl | serverSide2.js:17:38:17:46 | targetUrl | provenance | |
| serverSide2.js:16:23:16:41 | req.parsedQuery.url | serverSide2.js:16:11:16:41 | targetUrl | provenance | |
| serverSide2.js:19:11:19:55 | targetUrl1 | serverSide2.js:20:39:20:48 | targetUrl1 | provenance | |
| serverSide2.js:19:24:19:51 | req.par ... rsedUrl | serverSide2.js:19:11:19:55 | targetUrl1 | provenance | |
| serverSide2.js:22:11:22:36 | targetUrl2 | serverSide2.js:23:39:23:48 | targetUrl2 | provenance | |
| serverSide2.js:22:24:22:30 | req.url | serverSide2.js:22:11:22:36 | targetUrl2 | provenance | |
| serverSide2.js:25:11:25:47 | targetUrl3 | serverSide2.js:26:39:26:48 | targetUrl3 | provenance | |
| serverSide2.js:25:24:25:41 | req.SomeObject.url | serverSide2.js:25:11:25:47 | targetUrl3 | provenance | |
| serverSide.js:14:9:14:52 | tainted | serverSide.js:18:13:18:19 | tainted | provenance | |
| serverSide.js:14:9:14:52 | tainted | serverSide.js:20:17:20:23 | tainted | provenance | |
| serverSide.js:14:9:14:52 | tainted | serverSide.js:23:19:23:25 | tainted | provenance | |
@@ -163,6 +179,22 @@ nodes
| axiosInterceptors.serverSide.js:19:21:19:28 | req.body | semmle.label | req.body |
| axiosInterceptors.serverSide.js:20:5:20:25 | userProvidedUrl | semmle.label | userProvidedUrl |
| axiosInterceptors.serverSide.js:20:23:20:25 | url | semmle.label | url |
| serverSide2.js:9:34:9:63 | qs.pars ... .query) | semmle.label | qs.pars ... .query) |
| serverSide2.js:9:43:9:56 | req._parsedUrl | semmle.label | req._parsedUrl |
| serverSide2.js:10:25:10:31 | req.url | semmle.label | req.url |
| serverSide2.js:11:24:11:30 | req.url | semmle.label | req.url |
| serverSide2.js:16:11:16:41 | targetUrl | semmle.label | targetUrl |
| serverSide2.js:16:23:16:41 | req.parsedQuery.url | semmle.label | req.parsedQuery.url |
| serverSide2.js:17:38:17:46 | targetUrl | semmle.label | targetUrl |
| serverSide2.js:19:11:19:55 | targetUrl1 | semmle.label | targetUrl1 |
| serverSide2.js:19:24:19:51 | req.par ... rsedUrl | semmle.label | req.par ... rsedUrl |
| serverSide2.js:20:39:20:48 | targetUrl1 | semmle.label | targetUrl1 |
| serverSide2.js:22:11:22:36 | targetUrl2 | semmle.label | targetUrl2 |
| serverSide2.js:22:24:22:30 | req.url | semmle.label | req.url |
| serverSide2.js:23:39:23:48 | targetUrl2 | semmle.label | targetUrl2 |
| serverSide2.js:25:11:25:47 | targetUrl3 | semmle.label | targetUrl3 |
| serverSide2.js:25:24:25:41 | req.SomeObject.url | semmle.label | req.SomeObject.url |
| serverSide2.js:26:39:26:48 | targetUrl3 | semmle.label | targetUrl3 |
| serverSide.js:14:9:14:52 | tainted | semmle.label | tainted |
| serverSide.js:14:19:14:42 | url.par ... , true) | semmle.label | url.par ... , true) |
| serverSide.js:14:29:14:35 | req.url | semmle.label | req.url |

View File

@@ -0,0 +1,27 @@
const express = require('express');
const axios = require('axios');
const qs = require('qs');
const app = express();
const PORT = 3000;
app.use((req, res, next) => {
req.parsedQueryFromParsedUrl = qs.parse(req._parsedUrl.query); // $Source[js/request-forgery]
req.parsedQuery.url = req.url || {}; // $Source[js/request-forgery]
req.SomeObject.url = req.url; // $Source[js/request-forgery]
next();
});
app.get('/proxy', async (req, res) => {
const targetUrl = req.parsedQuery.url;
const response = await axios.get(targetUrl); // $Alert[js/request-forgery]
const targetUrl1 = req.parsedQueryFromParsedUrl.url;
const response1 = await axios.get(targetUrl1); // $Alert[js/request-forgery]
const targetUrl2 = req.url || {}; // $Source[js/request-forgery]
const response2 = await axios.get(targetUrl2); // $Alert[js/request-forgery]
const targetUrl3 = req.SomeObject.url || {};
const response3 = await axios.get(targetUrl3); // $Alert[js/request-forgery]
});

View File

@@ -62,6 +62,7 @@ pub struct Config {
pub qltest: bool,
pub qltest_cargo_check: bool,
pub qltest_dependencies: Vec<String>,
pub qltest_use_nightly: bool,
pub sysroot: Option<PathBuf>,
pub sysroot_src: Option<PathBuf>,
pub rustc_src: Option<PathBuf>,

View File

@@ -103,6 +103,7 @@ impl<'a> Extractor<'a> {
}
}
translator.emit_source_file(&ast);
translator.emit_truncated_diagnostics_message();
translator.trap.commit().unwrap_or_else(|err| {
error!(
"Failed to write trap file for: {}: {}",

View File

@@ -8,6 +8,9 @@ use std::path::Path;
use std::process::Command;
use tracing::info;
const EDITION: &str = "2021";
const NIGHTLY: &str = "nightly-2025-06-01";
fn dump_lib() -> anyhow::Result<()> {
let path_iterator = glob("*.rs").context("globbing test sources")?;
let paths = path_iterator
@@ -29,8 +32,11 @@ enum TestCargoManifest<'a> {
uses_proc_macro: bool,
uses_main: bool,
dependencies: &'a [String],
edition: &'a str,
},
Macro {
edition: &'a str,
},
Macro {},
}
impl TestCargoManifest<'_> {
@@ -56,16 +62,26 @@ fn dump_cargo_manifest(dependencies: &[String]) -> anyhow::Result<()> {
uses_proc_macro,
uses_main: fs::exists("main.rs").context("checking existence of main.rs")?,
dependencies,
edition: EDITION,
};
if uses_proc_macro {
TestCargoManifest::Workspace {}.dump("")?;
lib_manifest.dump(".lib")?;
TestCargoManifest::Macro {}.dump(".proc_macro")
TestCargoManifest::Macro { edition: EDITION }.dump(".proc_macro")
} else {
lib_manifest.dump("")
}
}
fn dump_nightly_toolchain() -> anyhow::Result<()> {
fs::write(
"rust-toolchain.toml",
format!("[toolchain]\nchannel = \"{NIGHTLY}\"\n"),
)
.context("writing rust-toolchain.toml")?;
Ok(())
}
fn set_sources(config: &mut Config) -> anyhow::Result<()> {
let path_iterator = glob("**/*.rs").context("globbing test sources")?;
config.inputs = path_iterator
@@ -79,6 +95,9 @@ pub(crate) fn prepare(config: &mut Config) -> anyhow::Result<()> {
dump_lib()?;
set_sources(config)?;
dump_cargo_manifest(&config.qltest_dependencies)?;
if config.qltest_use_nightly {
dump_nightly_toolchain()?;
}
if config.qltest_cargo_check {
let status = Command::new("cargo")
.env("RUSTFLAGS", "-Awarnings")

View File

@@ -11,7 +11,7 @@ members = [".lib", ".proc_macro"]
[package]
name = "test"
version = "0.0.1"
edition = "2021"
edition = "{{ edition }}"
[lib]
path = "{{#uses_proc_macro}}../{{/uses_proc_macro}}lib.rs"
{{#uses_main}}
@@ -32,7 +32,7 @@ proc_macro = { path = "../.proc_macro" }
[package]
name = "proc_macro"
version = "0.0.1"
edition = "2021"
edition = "{{ edition }}"
[lib]
path = "../proc_macro.rs"
proc_macro = true

View File

@@ -26,12 +26,38 @@ use ra_ap_syntax::{
macro_rules! pre_emit {
(Item, $self:ident, $node:ident) => {
if let Some(label) = $self.prepare_item_expansion($node) {
return Some(label);
return Some(label.into());
}
};
(AssocItem, $self:ident, $node:ident) => {
if let Some(label) = $self.prepare_item_expansion(&$node.clone().into()) {
return Some(label.into());
}
};
(ExternItem, $self:ident, $node:ident) => {
if let Some(label) = $self.prepare_item_expansion(&$node.clone().into()) {
return Some(label.into());
}
};
($($_:tt)*) => {};
}
// TODO: remove the mannually written Label conversions. These can be auto-generated by
// changing the base class of AssocItem from AstNode to Item
impl From<crate::trap::Label<generated::AssocItem>> for crate::trap::Label<generated::Item> {
fn from(value: crate::trap::Label<generated::AssocItem>) -> Self {
// SAFETY: this is safe because every concrete instance of `@assoc_item` is also an instance of `@item`
unsafe { Self::from_untyped(value.as_untyped()) }
}
}
// TODO: remove the mannually written Label conversions. These can be auto-generated by
// changing the base class of ExternItem from AstNode to Item
impl From<crate::trap::Label<generated::ExternItem>> for crate::trap::Label<generated::Item> {
fn from(value: crate::trap::Label<generated::ExternItem>) -> Self {
// SAFETY: this is safe because every concrete instance of `@extern_item` is also an instance of `@item`
unsafe { Self::from_untyped(value.as_untyped()) }
}
}
#[macro_export]
macro_rules! post_emit {
(MacroCall, $self:ident, $node:ident, $label:ident) => {
@@ -65,6 +91,18 @@ macro_rules! post_emit {
(Item, $self:ident, $node:ident, $label:ident) => {
$self.emit_item_expansion($node, $label);
};
(AssocItem, $self:ident, $node:ident, $label:ident) => {
$self.emit_item_expansion(
&$node.clone().into(),
From::<Label<generated::AssocItem>>::from($label),
);
};
(ExternItem, $self:ident, $node:ident, $label:ident) => {
$self.emit_item_expansion(
&$node.clone().into(),
From::<Label<generated::ExternItem>>::from($label),
);
};
// TODO canonical origin of other items
(PathExpr, $self:ident, $node:ident, $label:ident) => {
$self.extract_path_canonical_destination($node, $label.into());
@@ -126,11 +164,14 @@ pub struct Translator<'a> {
resolve_paths: bool,
source_kind: SourceKind,
macro_context_depth: usize,
diagnostic_count: usize,
}
const UNKNOWN_LOCATION: (LineCol, LineCol) =
(LineCol { line: 0, col: 0 }, LineCol { line: 0, col: 0 });
const DIAGNOSTIC_LIMIT_PER_FILE: usize = 100;
impl<'a> Translator<'a> {
pub fn new(
trap: TrapFile,
@@ -151,6 +192,7 @@ impl<'a> Translator<'a> {
resolve_paths: resolve_paths == ResolvePaths::Yes,
source_kind,
macro_context_depth: 0,
diagnostic_count: 0,
}
}
fn location(&self, range: TextRange) -> Option<(LineCol, LineCol)> {
@@ -237,6 +279,36 @@ impl<'a> Translator<'a> {
} else {
severity
};
if severity > DiagnosticSeverity::Debug {
self.diagnostic_count += 1;
if self.diagnostic_count > DIAGNOSTIC_LIMIT_PER_FILE {
return;
}
}
self.emit_diagnostic_unchecked(severity, tag, message, full_message, location);
}
pub fn emit_truncated_diagnostics_message(&mut self) {
if self.diagnostic_count > DIAGNOSTIC_LIMIT_PER_FILE {
let count = self.diagnostic_count - DIAGNOSTIC_LIMIT_PER_FILE;
self.emit_diagnostic_unchecked(
DiagnosticSeverity::Warning,
"diagnostics".to_owned(),
"Too many diagnostic messages".to_owned(),
format!(
"Too many diagnostic messages, {count} diagnostic messages were suppressed"
),
UNKNOWN_LOCATION,
);
}
}
fn emit_diagnostic_unchecked(
&mut self,
severity: DiagnosticSeverity,
tag: String,
message: String,
full_message: String,
location: (LineCol, LineCol),
) {
let (start, end) = location;
dispatch_to_tracing!(
severity,
@@ -716,10 +788,21 @@ impl<'a> Translator<'a> {
}
}
fn is_attribute_macro_target(&self, node: &ast::Item) -> bool {
// rust-analyzer considers as an `attr_macro_call` also a plain macro call, but we want to
// process that differently (in `extract_macro_call_expanded`)
!matches!(node, ast::Item::MacroCall(_))
&& self.semantics.is_some_and(|semantics| {
let file = semantics.hir_file_for(node.syntax());
let node = InFile::new(file, node);
semantics.is_attr_macro_call(node)
})
}
pub(crate) fn prepare_item_expansion(
&mut self,
node: &ast::Item,
) -> Option<Label<generated::Item>> {
) -> Option<Label<generated::MacroCall>> {
if self.source_kind == SourceKind::Library {
// if the item expands via an attribute macro, we want to only emit the expansion
if let Some(expanded) = self.emit_attribute_macro_expansion(node) {
@@ -736,13 +819,10 @@ impl<'a> Translator<'a> {
expanded.into(),
&mut self.trap.writer,
);
return Some(label.into());
return Some(label);
}
}
let semantics = self.semantics.as_ref()?;
let file = semantics.hir_file_for(node.syntax());
let node = InFile::new(file, node);
if semantics.is_attr_macro_call(node) {
if self.is_attribute_macro_target(node) {
self.macro_context_depth += 1;
}
None
@@ -785,10 +865,7 @@ impl<'a> Translator<'a> {
&mut self,
node: &ast::Item,
) -> Option<Label<generated::MacroItems>> {
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) {
if !self.is_attribute_macro_target(node) {
return None;
}
self.macro_context_depth -= 1;
@@ -796,7 +873,7 @@ impl<'a> Translator<'a> {
// only expand the outermost attribute macro
return None;
}
let expansion = semantics.expand_attr_macro(node)?;
let expansion = self.semantics?.expand_attr_macro(node)?;
self.process_item_macro_expansion(node, expansion)
}

View File

@@ -205,7 +205,11 @@ abstract class ItemNode extends Locatable {
else result = this.getImmediateParentModule().getImmediateParentModule()
or
name = "self" and
if this instanceof Module or this instanceof Enum or this instanceof Struct
if
this instanceof Module or
this instanceof Enum or
this instanceof Struct or
this instanceof Crate
then result = this
else result = this.getImmediateParentModule()
or

View File

@@ -1,6 +1,9 @@
Cargo.toml
lib.rs
target/
# these are all generated, see `rust/extractor/src/qltest.rs` for details
Cargo.toml
rust-toolchain.toml
lib.rs
.proc_macro/
.lib/

View File

@@ -410,6 +410,151 @@ macro_expansion.rs:
# 30| getItem(6): [Impl] impl S { ... }
# 30| getAssocItemList(): [AssocItemList] AssocItemList
# 31| getAssocItem(0): [Function] fn bzz
# 32| getAttributeMacroExpansion(): [MacroItems] MacroItems
# 32| getItem(0): [Function] fn bzz_0
# 32| getParamList(): [ParamList] ParamList
# 32| getBody(): [BlockExpr] { ... }
# 32| getStmtList(): [StmtList] StmtList
# 33| getStatement(0): [ExprStmt] ExprStmt
# 33| getExpr(): [MacroExpr] MacroExpr
# 33| getMacroCall(): [MacroCall] hello!...
# 33| getPath(): [Path] hello
# 33| getSegment(): [PathSegment] hello
# 33| getIdentifier(): [NameRef] hello
# 33| getTokenTree(): [TokenTree] TokenTree
# 31| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
# 31| getStatement(0): [ExprStmt] ExprStmt
# 31| getExpr(): [MacroExpr] MacroExpr
# 31| getMacroCall(): [MacroCall] println!...
# 31| getPath(): [Path] println
# 31| getSegment(): [PathSegment] println
# 31| getIdentifier(): [NameRef] println
# 31| getTokenTree(): [TokenTree] TokenTree
# 31| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
# 31| getTailExpr(): [BlockExpr] { ... }
# 31| getStmtList(): [StmtList] StmtList
# 31| getStatement(0): [ExprStmt] ExprStmt
# 31| getExpr(): [CallExpr] ...::_print(...)
# 31| getArgList(): [ArgList] ArgList
# 31| getArg(0): [MacroExpr] MacroExpr
# 31| getMacroCall(): [MacroCall] ...::format_args_nl!...
# 31| getPath(): [Path] ...::format_args_nl
# 31| getQualifier(): [Path] $crate
# 31| getSegment(): [PathSegment] $crate
# 31| getIdentifier(): [NameRef] $crate
# 31| getSegment(): [PathSegment] format_args_nl
# 31| getIdentifier(): [NameRef] format_args_nl
# 31| getTokenTree(): [TokenTree] TokenTree
# 31| getMacroCallExpansion(): [FormatArgsExpr] FormatArgsExpr
# 31| getTemplate(): [StringLiteralExpr] "hello!\n"
# 31| getFunction(): [PathExpr] ...::_print
# 31| getPath(): [Path] ...::_print
# 31| getQualifier(): [Path] ...::io
# 31| getQualifier(): [Path] $crate
# 31| getSegment(): [PathSegment] $crate
# 31| getIdentifier(): [NameRef] $crate
# 31| getSegment(): [PathSegment] io
# 31| getIdentifier(): [NameRef] io
# 31| getSegment(): [PathSegment] _print
# 31| getIdentifier(): [NameRef] _print
# 32| getName(): [Name] bzz_0
# 32| getVisibility(): [Visibility] Visibility
# 32| getItem(1): [Function] fn bzz_1
# 32| getParamList(): [ParamList] ParamList
# 32| getBody(): [BlockExpr] { ... }
# 32| getStmtList(): [StmtList] StmtList
# 33| getStatement(0): [ExprStmt] ExprStmt
# 33| getExpr(): [MacroExpr] MacroExpr
# 33| getMacroCall(): [MacroCall] hello!...
# 33| getPath(): [Path] hello
# 33| getSegment(): [PathSegment] hello
# 33| getIdentifier(): [NameRef] hello
# 33| getTokenTree(): [TokenTree] TokenTree
# 31| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
# 31| getStatement(0): [ExprStmt] ExprStmt
# 31| getExpr(): [MacroExpr] MacroExpr
# 31| getMacroCall(): [MacroCall] println!...
# 31| getPath(): [Path] println
# 31| getSegment(): [PathSegment] println
# 31| getIdentifier(): [NameRef] println
# 31| getTokenTree(): [TokenTree] TokenTree
# 31| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
# 31| getTailExpr(): [BlockExpr] { ... }
# 31| getStmtList(): [StmtList] StmtList
# 31| getStatement(0): [ExprStmt] ExprStmt
# 31| getExpr(): [CallExpr] ...::_print(...)
# 31| getArgList(): [ArgList] ArgList
# 31| getArg(0): [MacroExpr] MacroExpr
# 31| getMacroCall(): [MacroCall] ...::format_args_nl!...
# 31| getPath(): [Path] ...::format_args_nl
# 31| getQualifier(): [Path] $crate
# 31| getSegment(): [PathSegment] $crate
# 31| getIdentifier(): [NameRef] $crate
# 31| getSegment(): [PathSegment] format_args_nl
# 31| getIdentifier(): [NameRef] format_args_nl
# 31| getTokenTree(): [TokenTree] TokenTree
# 31| getMacroCallExpansion(): [FormatArgsExpr] FormatArgsExpr
# 31| getTemplate(): [StringLiteralExpr] "hello!\n"
# 31| getFunction(): [PathExpr] ...::_print
# 31| getPath(): [Path] ...::_print
# 31| getQualifier(): [Path] ...::io
# 31| getQualifier(): [Path] $crate
# 31| getSegment(): [PathSegment] $crate
# 31| getIdentifier(): [NameRef] $crate
# 31| getSegment(): [PathSegment] io
# 31| getIdentifier(): [NameRef] io
# 31| getSegment(): [PathSegment] _print
# 31| getIdentifier(): [NameRef] _print
# 32| getName(): [Name] bzz_1
# 32| getVisibility(): [Visibility] Visibility
# 32| getItem(2): [Function] fn bzz_2
# 32| getParamList(): [ParamList] ParamList
# 32| getBody(): [BlockExpr] { ... }
# 32| getStmtList(): [StmtList] StmtList
# 33| getStatement(0): [ExprStmt] ExprStmt
# 33| getExpr(): [MacroExpr] MacroExpr
# 33| getMacroCall(): [MacroCall] hello!...
# 33| getPath(): [Path] hello
# 33| getSegment(): [PathSegment] hello
# 33| getIdentifier(): [NameRef] hello
# 33| getTokenTree(): [TokenTree] TokenTree
# 31| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
# 31| getStatement(0): [ExprStmt] ExprStmt
# 31| getExpr(): [MacroExpr] MacroExpr
# 31| getMacroCall(): [MacroCall] println!...
# 31| getPath(): [Path] println
# 31| getSegment(): [PathSegment] println
# 31| getIdentifier(): [NameRef] println
# 31| getTokenTree(): [TokenTree] TokenTree
# 31| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
# 31| getTailExpr(): [BlockExpr] { ... }
# 31| getStmtList(): [StmtList] StmtList
# 31| getStatement(0): [ExprStmt] ExprStmt
# 31| getExpr(): [CallExpr] ...::_print(...)
# 31| getArgList(): [ArgList] ArgList
# 31| getArg(0): [MacroExpr] MacroExpr
# 31| getMacroCall(): [MacroCall] ...::format_args_nl!...
# 31| getPath(): [Path] ...::format_args_nl
# 31| getQualifier(): [Path] $crate
# 31| getSegment(): [PathSegment] $crate
# 31| getIdentifier(): [NameRef] $crate
# 31| getSegment(): [PathSegment] format_args_nl
# 31| getIdentifier(): [NameRef] format_args_nl
# 31| getTokenTree(): [TokenTree] TokenTree
# 31| getMacroCallExpansion(): [FormatArgsExpr] FormatArgsExpr
# 31| getTemplate(): [StringLiteralExpr] "hello!\n"
# 31| getFunction(): [PathExpr] ...::_print
# 31| getPath(): [Path] ...::_print
# 31| getQualifier(): [Path] ...::io
# 31| getQualifier(): [Path] $crate
# 31| getSegment(): [PathSegment] $crate
# 31| getIdentifier(): [NameRef] $crate
# 31| getSegment(): [PathSegment] io
# 31| getIdentifier(): [NameRef] io
# 31| getSegment(): [PathSegment] _print
# 31| getIdentifier(): [NameRef] _print
# 32| getName(): [Name] bzz_2
# 32| getVisibility(): [Visibility] Visibility
# 32| getParamList(): [ParamList] ParamList
# 31| getAttr(0): [Attr] Attr
# 31| getMeta(): [Meta] Meta
@@ -426,41 +571,6 @@ macro_expansion.rs:
# 33| getSegment(): [PathSegment] hello
# 33| getIdentifier(): [NameRef] hello
# 33| getTokenTree(): [TokenTree] TokenTree
# 33| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
# 33| getStatement(0): [ExprStmt] ExprStmt
# 33| getExpr(): [MacroExpr] MacroExpr
# 33| getMacroCall(): [MacroCall] println!...
# 33| getPath(): [Path] println
# 33| getSegment(): [PathSegment] println
# 33| getIdentifier(): [NameRef] println
# 33| getTokenTree(): [TokenTree] TokenTree
# 33| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
# 33| getTailExpr(): [BlockExpr] { ... }
# 33| getStmtList(): [StmtList] StmtList
# 33| getStatement(0): [ExprStmt] ExprStmt
# 33| getExpr(): [CallExpr] ...::_print(...)
# 33| getArgList(): [ArgList] ArgList
# 33| getArg(0): [MacroExpr] MacroExpr
# 33| getMacroCall(): [MacroCall] ...::format_args_nl!...
# 33| getPath(): [Path] ...::format_args_nl
# 33| getQualifier(): [Path] $crate
# 33| getSegment(): [PathSegment] $crate
# 33| getIdentifier(): [NameRef] $crate
# 33| getSegment(): [PathSegment] format_args_nl
# 33| getIdentifier(): [NameRef] format_args_nl
# 33| getTokenTree(): [TokenTree] TokenTree
# 33| getMacroCallExpansion(): [FormatArgsExpr] FormatArgsExpr
# 33| getTemplate(): [StringLiteralExpr] "hello!\n"
# 33| getFunction(): [PathExpr] ...::_print
# 33| getPath(): [Path] ...::_print
# 33| getQualifier(): [Path] ...::io
# 33| getQualifier(): [Path] $crate
# 33| getSegment(): [PathSegment] $crate
# 33| getIdentifier(): [NameRef] $crate
# 33| getSegment(): [PathSegment] io
# 33| getIdentifier(): [NameRef] io
# 33| getSegment(): [PathSegment] _print
# 33| getIdentifier(): [NameRef] _print
# 32| getName(): [Name] bzz
# 32| getVisibility(): [Visibility] Visibility
# 30| getSelfTy(): [PathTypeRepr] S

View File

@@ -11,6 +11,9 @@ attribute_macros
| macro_expansion.rs:15:1:16:14 | fn bar_0 | 1 | macro_expansion.rs:16:1:16:14 | fn bar_0_new |
| macro_expansion.rs:15:1:16:14 | fn bar_1 | 0 | macro_expansion.rs:16:1:16:14 | fn bar_1 |
| macro_expansion.rs:15:1:16:14 | fn bar_1 | 1 | macro_expansion.rs:16:1:16:14 | fn bar_1_new |
| macro_expansion.rs:31:5:34:5 | fn bzz | 0 | macro_expansion.rs:32:5:33:17 | fn bzz_0 |
| macro_expansion.rs:31:5:34:5 | fn bzz | 1 | macro_expansion.rs:32:5:33:17 | fn bzz_1 |
| macro_expansion.rs:31:5:34:5 | fn bzz | 2 | macro_expansion.rs:32:5:33:17 | fn bzz_2 |
derive_macros
| macro_expansion.rs:83:1:86:1 | struct MyDerive | 0 | 0 | macro_expansion.rs:84:8:85:9 | impl ...::Debug for MyDerive::<...> { ... } |
| macro_expansion.rs:88:1:92:1 | enum MyDeriveEnum | 0 | 0 | macro_expansion.rs:89:6:91:12 | impl ...::PartialEq for MyDeriveEnum::<...> { ... } |
@@ -21,9 +24,15 @@ macro_calls
| included/included.rs:2:9:2:39 | concat!... | included/included.rs:2:17:2:38 | "Hello world!" |
| macro_expansion.rs:5:9:5:34 | concat!... | macro_expansion.rs:5:17:5:34 | "Hello world!" |
| macro_expansion.rs:5:9:5:34 | concat!... | macro_expansion.rs:5:17:5:34 | "Hello world!" |
| macro_expansion.rs:33:9:33:16 | ...::format_args_nl!... | macro_expansion.rs:33:9:33:16 | FormatArgsExpr |
| macro_expansion.rs:33:9:33:16 | hello!... | macro_expansion.rs:33:9:33:16 | MacroBlockExpr |
| macro_expansion.rs:33:9:33:16 | println!... | macro_expansion.rs:33:9:33:16 | MacroBlockExpr |
| macro_expansion.rs:31:5:31:16 | ...::format_args_nl!... | macro_expansion.rs:31:5:31:16 | FormatArgsExpr |
| macro_expansion.rs:31:5:31:16 | ...::format_args_nl!... | macro_expansion.rs:31:5:31:16 | FormatArgsExpr |
| macro_expansion.rs:31:5:31:16 | ...::format_args_nl!... | macro_expansion.rs:31:5:31:16 | FormatArgsExpr |
| macro_expansion.rs:31:5:31:16 | println!... | macro_expansion.rs:31:5:31:16 | MacroBlockExpr |
| macro_expansion.rs:31:5:31:16 | println!... | macro_expansion.rs:31:5:31:16 | MacroBlockExpr |
| macro_expansion.rs:31:5:31:16 | println!... | macro_expansion.rs:31:5:31:16 | MacroBlockExpr |
| macro_expansion.rs:33:9:33:15 | hello!... | macro_expansion.rs:31:5:31:16 | MacroBlockExpr |
| macro_expansion.rs:33:9:33:15 | hello!... | macro_expansion.rs:31:5:31:16 | MacroBlockExpr |
| macro_expansion.rs:33:9:33:15 | hello!... | macro_expansion.rs:31:5:31:16 | MacroBlockExpr |
| macro_expansion.rs:44:5:44:13 | def_x!... | macro_expansion.rs:44:5:44:13 | MacroItems |
| macro_expansion.rs:53:9:53:25 | concat!... | macro_expansion.rs:53:17:53:24 | "xy" |
| macro_expansion.rs:55:9:58:5 | my_macro!... | macro_expansion.rs:56:9:57:13 | MacroExpr |
@@ -40,4 +49,5 @@ macro_calls
| macro_expansion.rs:79:12:79:20 | my_int!... | macro_expansion.rs:79:12:79:20 | i32 |
unexpanded_macro_calls
| macro_expansion.rs:5:9:5:35 | concat!... |
| macro_expansion.rs:33:9:33:16 | hello!... |
warnings

View File

@@ -3,7 +3,7 @@ multiplePathResolutions
| main.rs:118:9:118:9 | f | main.rs:110:5:112:5 | fn f |
| main.rs:626:3:626:12 | proc_macro | file://:0:0:0:0 | Crate(proc_macro@0.0.0) |
| main.rs:626:3:626:12 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) |
| main.rs:631:7:631:16 | proc_macro | file://:0:0:0:0 | Crate(proc_macro@0.0.0) |
| main.rs:631:7:631:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) |
| main.rs:634:7:634:16 | proc_macro | file://:0:0:0:0 | Crate(proc_macro@0.0.0) |
| main.rs:634:7:634:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) |
| main.rs:632:7:632:16 | proc_macro | file://:0:0:0:0 | Crate(proc_macro@0.0.0) |
| main.rs:632:7:632:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) |
| main.rs:635:7:635:16 | proc_macro | file://:0:0:0:0 | Crate(proc_macro@0.0.0) |
| main.rs:635:7:635:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) |

View File

@@ -627,7 +627,8 @@ extern crate self as zelf;
fn z() {} // I122
struct AStruct {} //I123
impl AStruct { // $ item=I123
impl AStruct // $ item=I123
{
#[proc_macro::add_suffix("on_type")] // $ item=add_suffix
pub fn z() {} // I124
@@ -635,6 +636,10 @@ impl AStruct { // $ item=I123
pub fn z(&self) {} // I125
}
use std::{self as ztd}; // $ item=std
fn use_ztd(x: ztd::string::String) {} // $ item=String
fn main() {
my::nested::nested1::nested2::f(); // $ item=I4
my::f(); // $ item=I38
@@ -667,6 +672,6 @@ fn main() {
zelf::h(); // $ item=I25
z_changed(); // $ MISSING: item=I122
AStruct::z_on_type(); // $ MISSING: item=I124
AStruct{} // $ item=I123
AStruct {} // $ item=I123
.z_on_instance(); // MISSING: item=I125
}

View File

@@ -61,7 +61,7 @@ resolvePath
| main.rs:30:17:30:21 | super | main.rs:18:5:36:5 | mod m2 |
| main.rs:30:17:30:24 | ...::f | main.rs:19:9:21:9 | fn f |
| main.rs:33:17:33:17 | f | main.rs:19:9:21:9 | fn f |
| main.rs:40:9:40:13 | super | main.rs:1:1:672:2 | SourceFile |
| main.rs:40:9:40:13 | super | main.rs:1:1:677:2 | SourceFile |
| main.rs:40:9:40:17 | ...::m1 | main.rs:13:1:37:1 | mod m1 |
| main.rs:40:9:40:21 | ...::m2 | main.rs:18:5:36:5 | mod m2 |
| main.rs:40:9:40:24 | ...::g | main.rs:23:9:27:9 | fn g |
@@ -73,7 +73,7 @@ resolvePath
| main.rs:61:17:61:19 | Foo | main.rs:59:9:59:21 | struct Foo |
| main.rs:64:13:64:15 | Foo | main.rs:53:5:53:17 | struct Foo |
| main.rs:66:5:66:5 | f | main.rs:55:5:62:5 | fn f |
| main.rs:68:5:68:8 | self | main.rs:1:1:672:2 | SourceFile |
| main.rs:68:5:68:8 | self | main.rs:1:1:677:2 | SourceFile |
| main.rs:68:5:68:11 | ...::i | main.rs:71:1:83:1 | fn i |
| main.rs:74:13:74:15 | Foo | main.rs:48:1:48:13 | struct Foo |
| main.rs:78:16:78:18 | i32 | {EXTERNAL LOCATION} | struct i32 |
@@ -88,7 +88,7 @@ resolvePath
| main.rs:87:57:87:66 | ...::g | my2/nested2.rs:7:9:9:9 | fn g |
| main.rs:87:80:87:86 | nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 |
| main.rs:100:5:100:22 | f_defined_in_macro | main.rs:99:18:99:42 | fn f_defined_in_macro |
| main.rs:117:13:117:17 | super | main.rs:1:1:672:2 | SourceFile |
| main.rs:117:13:117:17 | super | main.rs:1:1:677:2 | SourceFile |
| main.rs:117:13:117:21 | ...::m5 | main.rs:103:1:107:1 | mod m5 |
| main.rs:118:9:118:9 | f | main.rs:104:5:106:5 | fn f |
| main.rs:118:9:118:9 | f | main.rs:110:5:112:5 | fn f |
@@ -270,75 +270,80 @@ resolvePath
| main.rs:626:3:626:12 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) |
| main.rs:626:3:626:24 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix |
| main.rs:630:6:630:12 | AStruct | main.rs:629:1:629:17 | struct AStruct |
| main.rs:631:7:631:16 | proc_macro | {EXTERNAL LOCATION} | Crate(proc_macro@0.0.0) |
| main.rs:631:7:631:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) |
| main.rs:631:7:631:28 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix |
| main.rs:634:7:634:16 | proc_macro | {EXTERNAL LOCATION} | Crate(proc_macro@0.0.0) |
| main.rs:634:7:634:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) |
| main.rs:634:7:634:28 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix |
| main.rs:639:5:639:6 | my | main.rs:1:1:1:7 | mod my |
| main.rs:639:5:639:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
| main.rs:639:5:639:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |
| main.rs:639:5:639:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 |
| main.rs:639:5:639:35 | ...::f | my/nested.rs:3:9:5:9 | fn f |
| main.rs:640:5:640:6 | my | main.rs:1:1:1:7 | mod my |
| main.rs:640:5:640:9 | ...::f | my.rs:5:1:7:1 | fn f |
| main.rs:641:5:641:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 |
| main.rs:641:5:641:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 |
| main.rs:641:5:641:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 |
| main.rs:641:5:641:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f |
| main.rs:642:5:642:5 | f | my2/nested2.rs:3:9:5:9 | fn f |
| main.rs:643:5:643:5 | g | my2/nested2.rs:7:9:9:9 | fn g |
| main.rs:644:5:644:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) |
| main.rs:644:5:644:12 | ...::h | main.rs:50:1:69:1 | fn h |
| main.rs:645:5:645:6 | m1 | main.rs:13:1:37:1 | mod m1 |
| main.rs:645:5:645:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 |
| main.rs:645:5:645:13 | ...::g | main.rs:23:9:27:9 | fn g |
| main.rs:646:5:646:6 | m1 | main.rs:13:1:37:1 | mod m1 |
| main.rs:646:5:646:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 |
| main.rs:646:5:646:14 | ...::m3 | main.rs:29:9:35:9 | mod m3 |
| main.rs:646:5:646:17 | ...::h | main.rs:30:27:34:13 | fn h |
| main.rs:647:5:647:6 | m4 | main.rs:39:1:46:1 | mod m4 |
| main.rs:647:5:647:9 | ...::i | main.rs:42:5:45:5 | fn i |
| main.rs:648:5:648:5 | h | main.rs:50:1:69:1 | fn h |
| main.rs:649:5:649:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f |
| main.rs:650:5:650:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g |
| main.rs:651:5:651:5 | j | main.rs:97:1:101:1 | fn j |
| main.rs:652:5:652:6 | m6 | main.rs:109:1:120:1 | mod m6 |
| main.rs:652:5:652:9 | ...::g | main.rs:114:5:119:5 | fn g |
| main.rs:653:5:653:6 | m7 | main.rs:122:1:141:1 | mod m7 |
| main.rs:653:5:653:9 | ...::f | main.rs:133:5:140:5 | fn f |
| main.rs:654:5:654:6 | m8 | main.rs:143:1:197:1 | mod m8 |
| main.rs:654:5:654:9 | ...::g | main.rs:181:5:196:5 | fn g |
| main.rs:655:5:655:6 | m9 | main.rs:199:1:207:1 | mod m9 |
| main.rs:655:5:655:9 | ...::f | main.rs:202:5:206:5 | fn f |
| main.rs:656:5:656:7 | m11 | main.rs:230:1:267:1 | mod m11 |
| main.rs:656:5:656:10 | ...::f | main.rs:235:5:238:5 | fn f |
| main.rs:657:5:657:7 | m15 | main.rs:298:1:352:1 | mod m15 |
| main.rs:657:5:657:10 | ...::f | main.rs:339:5:351:5 | fn f |
| main.rs:658:5:658:7 | m16 | main.rs:354:1:446:1 | mod m16 |
| main.rs:658:5:658:10 | ...::f | main.rs:421:5:445:5 | fn f |
| main.rs:659:5:659:7 | m17 | main.rs:448:1:478:1 | mod m17 |
| main.rs:659:5:659:10 | ...::f | main.rs:472:5:477:5 | fn f |
| main.rs:660:5:660:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 |
| main.rs:660:5:660:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f |
| main.rs:661:5:661:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 |
| main.rs:661:5:661:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f |
| main.rs:662:5:662:7 | my3 | my2/mod.rs:12:1:12:12 | mod my3 |
| main.rs:662:5:662:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f |
| main.rs:663:5:663:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
| main.rs:664:5:664:7 | m18 | main.rs:480:1:498:1 | mod m18 |
| main.rs:664:5:664:12 | ...::m19 | main.rs:485:5:497:5 | mod m19 |
| main.rs:664:5:664:17 | ...::m20 | main.rs:490:9:496:9 | mod m20 |
| main.rs:664:5:664:20 | ...::g | main.rs:491:13:495:13 | fn g |
| main.rs:665:5:665:7 | m23 | main.rs:527:1:552:1 | mod m23 |
| main.rs:665:5:665:10 | ...::f | main.rs:547:5:551:5 | fn f |
| main.rs:666:5:666:7 | m24 | main.rs:554:1:622:1 | mod m24 |
| main.rs:666:5:666:10 | ...::f | main.rs:608:5:621:5 | fn f |
| main.rs:667:5:667:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) |
| main.rs:667:5:667:11 | ...::h | main.rs:50:1:69:1 | fn h |
| main.rs:669:5:669:11 | AStruct | main.rs:629:1:629:17 | struct AStruct |
| main.rs:670:5:670:11 | AStruct | main.rs:629:1:629:17 | struct AStruct |
| main.rs:632:7:632:16 | proc_macro | {EXTERNAL LOCATION} | Crate(proc_macro@0.0.0) |
| main.rs:632:7:632:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) |
| main.rs:632:7:632:28 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix |
| main.rs:635:7:635:16 | proc_macro | {EXTERNAL LOCATION} | Crate(proc_macro@0.0.0) |
| main.rs:635:7:635:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) |
| main.rs:635:7:635:28 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix |
| main.rs:639:5:639:7 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) |
| main.rs:639:11:639:14 | self | {EXTERNAL LOCATION} | Crate(std@0.0.0) |
| main.rs:641:15:641:17 | ztd | {EXTERNAL LOCATION} | Crate(std@0.0.0) |
| main.rs:641:15:641:25 | ...::string | {EXTERNAL LOCATION} | mod string |
| main.rs:641:15:641:33 | ...::String | {EXTERNAL LOCATION} | struct String |
| main.rs:644:5:644:6 | my | main.rs:1:1:1:7 | mod my |
| main.rs:644:5:644:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
| main.rs:644:5:644:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |
| main.rs:644:5:644:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 |
| main.rs:644:5:644:35 | ...::f | my/nested.rs:3:9:5:9 | fn f |
| main.rs:645:5:645:6 | my | main.rs:1:1:1:7 | mod my |
| main.rs:645:5:645:9 | ...::f | my.rs:5:1:7:1 | fn f |
| main.rs:646:5:646:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 |
| main.rs:646:5:646:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 |
| main.rs:646:5:646:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 |
| main.rs:646:5:646:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f |
| main.rs:647:5:647:5 | f | my2/nested2.rs:3:9:5:9 | fn f |
| main.rs:648:5:648:5 | g | my2/nested2.rs:7:9:9:9 | fn g |
| main.rs:649:5:649:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) |
| main.rs:649:5:649:12 | ...::h | main.rs:50:1:69:1 | fn h |
| main.rs:650:5:650:6 | m1 | main.rs:13:1:37:1 | mod m1 |
| main.rs:650:5:650:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 |
| main.rs:650:5:650:13 | ...::g | main.rs:23:9:27:9 | fn g |
| main.rs:651:5:651:6 | m1 | main.rs:13:1:37:1 | mod m1 |
| main.rs:651:5:651:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 |
| main.rs:651:5:651:14 | ...::m3 | main.rs:29:9:35:9 | mod m3 |
| main.rs:651:5:651:17 | ...::h | main.rs:30:27:34:13 | fn h |
| main.rs:652:5:652:6 | m4 | main.rs:39:1:46:1 | mod m4 |
| main.rs:652:5:652:9 | ...::i | main.rs:42:5:45:5 | fn i |
| main.rs:653:5:653:5 | h | main.rs:50:1:69:1 | fn h |
| main.rs:654:5:654:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f |
| main.rs:655:5:655:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g |
| main.rs:656:5:656:5 | j | main.rs:97:1:101:1 | fn j |
| main.rs:657:5:657:6 | m6 | main.rs:109:1:120:1 | mod m6 |
| main.rs:657:5:657:9 | ...::g | main.rs:114:5:119:5 | fn g |
| main.rs:658:5:658:6 | m7 | main.rs:122:1:141:1 | mod m7 |
| main.rs:658:5:658:9 | ...::f | main.rs:133:5:140:5 | fn f |
| main.rs:659:5:659:6 | m8 | main.rs:143:1:197:1 | mod m8 |
| main.rs:659:5:659:9 | ...::g | main.rs:181:5:196:5 | fn g |
| main.rs:660:5:660:6 | m9 | main.rs:199:1:207:1 | mod m9 |
| main.rs:660:5:660:9 | ...::f | main.rs:202:5:206:5 | fn f |
| main.rs:661:5:661:7 | m11 | main.rs:230:1:267:1 | mod m11 |
| main.rs:661:5:661:10 | ...::f | main.rs:235:5:238:5 | fn f |
| main.rs:662:5:662:7 | m15 | main.rs:298:1:352:1 | mod m15 |
| main.rs:662:5:662:10 | ...::f | main.rs:339:5:351:5 | fn f |
| main.rs:663:5:663:7 | m16 | main.rs:354:1:446:1 | mod m16 |
| main.rs:663:5:663:10 | ...::f | main.rs:421:5:445:5 | fn f |
| main.rs:664:5:664:7 | m17 | main.rs:448:1:478:1 | mod m17 |
| main.rs:664:5:664:10 | ...::f | main.rs:472:5:477:5 | fn f |
| main.rs:665:5:665:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 |
| main.rs:665:5:665:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f |
| main.rs:666:5:666:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 |
| main.rs:666:5:666:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f |
| main.rs:667:5:667:7 | my3 | my2/mod.rs:12:1:12:12 | mod my3 |
| main.rs:667:5:667:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f |
| main.rs:668:5:668:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
| main.rs:669:5:669:7 | m18 | main.rs:480:1:498:1 | mod m18 |
| main.rs:669:5:669:12 | ...::m19 | main.rs:485:5:497:5 | mod m19 |
| main.rs:669:5:669:17 | ...::m20 | main.rs:490:9:496:9 | mod m20 |
| main.rs:669:5:669:20 | ...::g | main.rs:491:13:495:13 | fn g |
| main.rs:670:5:670:7 | m23 | main.rs:527:1:552:1 | mod m23 |
| main.rs:670:5:670:10 | ...::f | main.rs:547:5:551:5 | fn f |
| main.rs:671:5:671:7 | m24 | main.rs:554:1:622:1 | mod m24 |
| main.rs:671:5:671:10 | ...::f | main.rs:608:5:621:5 | fn f |
| main.rs:672:5:672:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) |
| main.rs:672:5:672:11 | ...::h | main.rs:50:1:69:1 | fn h |
| main.rs:674:5:674:11 | AStruct | main.rs:629:1:629:17 | struct AStruct |
| main.rs:675:5:675:11 | AStruct | main.rs:629:1:629:17 | struct AStruct |
| my2/mod.rs:5:5:5:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 |
| my2/mod.rs:5:5:5:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 |
| my2/mod.rs:5:5:5:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 |
@@ -354,7 +359,7 @@ resolvePath
| my2/my3/mod.rs:3:5:3:5 | g | my2/mod.rs:3:1:6:1 | fn g |
| my2/my3/mod.rs:4:5:4:5 | h | main.rs:50:1:69:1 | fn h |
| my2/my3/mod.rs:7:5:7:9 | super | my2/mod.rs:1:1:17:30 | SourceFile |
| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:672:2 | SourceFile |
| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:677:2 | SourceFile |
| my2/my3/mod.rs:7:5:7:19 | ...::h | main.rs:50:1:69:1 | fn h |
| my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:17:30 | SourceFile |
| my2/my3/mod.rs:8:5:8:12 | ...::g | my2/mod.rs:3:1:6:1 | fn g |

View File

@@ -1,2 +1,3 @@
qltest_use_nightly: true
qltest_dependencies:
- poem = { version = "3.1.7" }

View File

@@ -1,8 +0,0 @@
# This file specifies the Rust version used to develop and test the
# extractors written in rust. It is set to the lowest version of Rust
# we want to support.
[toolchain]
channel = "nightly"
profile = "minimal"
components = [ ]

View File

@@ -1,29 +1,29 @@
multiplePathResolutions
| main.rs:218:14:218:17 | libc | file://:0:0:0:0 | Crate(libc@0.2.173) |
| main.rs:218:14:218:17 | libc | file://:0:0:0:0 | Crate(libc@0.2.172) |
| main.rs:218:14:218:17 | libc | file://:0:0:0:0 | Crate(libc@0.2.174) |
| main.rs:218:14:218:25 | ...::malloc | file://:0:0:0:0 | fn malloc |
| main.rs:218:14:218:25 | ...::malloc | file://:0:0:0:0 | fn malloc |
| main.rs:219:13:219:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.173) |
| main.rs:219:13:219:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.172) |
| main.rs:219:13:219:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.174) |
| main.rs:219:13:219:24 | ...::malloc | file://:0:0:0:0 | fn malloc |
| main.rs:219:13:219:24 | ...::malloc | file://:0:0:0:0 | fn malloc |
| main.rs:220:13:220:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.173) |
| main.rs:220:13:220:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.172) |
| main.rs:220:13:220:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.174) |
| main.rs:220:13:220:31 | ...::aligned_alloc | file://:0:0:0:0 | fn aligned_alloc |
| main.rs:220:13:220:31 | ...::aligned_alloc | file://:0:0:0:0 | fn aligned_alloc |
| main.rs:221:13:221:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.173) |
| main.rs:221:13:221:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.172) |
| main.rs:221:13:221:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.174) |
| main.rs:221:13:221:31 | ...::aligned_alloc | file://:0:0:0:0 | fn aligned_alloc |
| main.rs:221:13:221:31 | ...::aligned_alloc | file://:0:0:0:0 | fn aligned_alloc |
| main.rs:222:13:222:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.173) |
| main.rs:222:13:222:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.172) |
| main.rs:222:13:222:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.174) |
| main.rs:222:13:222:24 | ...::calloc | file://:0:0:0:0 | fn calloc |
| main.rs:222:13:222:24 | ...::calloc | file://:0:0:0:0 | fn calloc |
| main.rs:223:13:223:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.173) |
| main.rs:223:13:223:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.172) |
| main.rs:223:13:223:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.174) |
| main.rs:223:13:223:24 | ...::calloc | file://:0:0:0:0 | fn calloc |
| main.rs:223:13:223:24 | ...::calloc | file://:0:0:0:0 | fn calloc |
| main.rs:224:13:224:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.173) |
| main.rs:224:13:224:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.172) |
| main.rs:224:13:224:16 | libc | file://:0:0:0:0 | Crate(libc@0.2.174) |
| main.rs:224:13:224:25 | ...::realloc | file://:0:0:0:0 | fn realloc |
| main.rs:224:13:224:25 | ...::realloc | file://:0:0:0:0 | fn realloc |

View File

@@ -4,9 +4,9 @@ version = 4
[[package]]
name = "libc"
version = "0.2.173"
version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "test"

View File

@@ -1,3 +1,3 @@
qltest_cargo_check: true
qltest_use_nightly: true
qltest_dependencies:
- libc = { version = "0.2.11" }
- libc = { version = "0.2.174" }

View File

@@ -1,2 +0,0 @@
[toolchain]
channel = "nightly"

View File

@@ -1,13 +1,13 @@
multiplePathResolutions
| deallocation.rs:106:16:106:19 | libc | file://:0:0:0:0 | Crate(libc@0.2.171) |
| deallocation.rs:106:16:106:19 | libc | file://:0:0:0:0 | Crate(libc@0.2.172) |
| deallocation.rs:106:16:106:19 | libc | file://:0:0:0:0 | Crate(libc@0.2.173) |
| deallocation.rs:106:16:106:27 | ...::malloc | file://:0:0:0:0 | fn malloc |
| deallocation.rs:106:16:106:27 | ...::malloc | file://:0:0:0:0 | fn malloc |
| deallocation.rs:112:3:112:6 | libc | file://:0:0:0:0 | Crate(libc@0.2.171) |
| deallocation.rs:112:3:112:6 | libc | file://:0:0:0:0 | Crate(libc@0.2.172) |
| deallocation.rs:112:3:112:6 | libc | file://:0:0:0:0 | Crate(libc@0.2.173) |
| deallocation.rs:112:3:112:12 | ...::free | file://:0:0:0:0 | fn free |
| deallocation.rs:112:3:112:12 | ...::free | file://:0:0:0:0 | fn free |
| deallocation.rs:112:29:112:32 | libc | file://:0:0:0:0 | Crate(libc@0.2.171) |
| deallocation.rs:112:29:112:32 | libc | file://:0:0:0:0 | Crate(libc@0.2.172) |
| deallocation.rs:112:29:112:32 | libc | file://:0:0:0:0 | Crate(libc@0.2.173) |
| deallocation.rs:260:11:260:22 | ...::from | file://:0:0:0:0 | fn from |
| deallocation.rs:260:11:260:22 | ...::from | file://:0:0:0:0 | fn from |

View File

@@ -1,3 +1,3 @@
qltest_cargo_check: true
qltest_use_nightly: true
qltest_dependencies:
- libc = { version = "0.2.11" }

View File

@@ -1,2 +0,0 @@
[toolchain]
channel = "nightly-2025-03-17"