Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions rust/ql/lib/codeql/rust/internal/Definitions.qll
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,34 @@ private class PositionalFormatArgumentUse extends Use instanceof PositionalForma
override string getUseType() { result = "format argument" }
}

private class PathUse extends Use instanceof Path {
override Definition getDefinition() { result.asItemNode() = resolvePath(this) }
private class PathUse extends Use instanceof PathSegment {
private Path path;

PathUse() { this = path.getSegment() }

private CallExpr getCall() { result.getFunction().(PathExpr).getPath() = path }

override Definition getDefinition() {
// Our call resolution logic may disambiguate some calls, so only use those
result.asItemNode() = this.getCall().getStaticTarget()
or
not exists(this.getCall()) and
Comment on lines +146 to +149
Copy link

Copilot AI Jun 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider caching the result of getCall() in a local variable or predicate to avoid traversing the AST twice in getDefinition, improving performance.

Suggested change
// Our call resolution logic may disambiguate some calls, so only use those
result.asItemNode() = this.getCall().getStaticTarget()
or
not exists(this.getCall()) and
// Cache the result of getCall() to avoid traversing the AST twice
CallExpr cachedCall = this.getCall();
// Our call resolution logic may disambiguate some calls, so only use those
result.asItemNode() = cachedCall.getStaticTarget()
or
not exists(cachedCall) and

Copilot uses AI. Check for mistakes.
result.asItemNode() = resolvePath(path)
}

override string getUseType() { result = "path" }
}

private class MethodUse extends Use instanceof NameRef {
private MethodCallExpr mc;

MethodUse() { this = mc.getIdentifier() }

override Definition getDefinition() { result.asItemNode() = mc.getStaticTarget() }

override string getUseType() { result = "method" }
}

private class FileUse extends Use instanceof Name {
override Definition getDefinition() {
exists(Module m |
Expand Down
48 changes: 28 additions & 20 deletions rust/ql/test/library-tests/definitions/Definitions.expected
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
| main.rs:3:5:3:7 | lib | lib.rs:1:1:1:1 | SourceFile | file |
| main.rs:9:22:9:26 | value | main.rs:9:50:9:54 | value | format argument |
| main.rs:9:29:9:33 | width | main.rs:6:9:6:13 | width | local variable |
| main.rs:9:36:9:44 | precision | main.rs:7:9:7:17 | precision | local variable |
| main.rs:10:22:10:22 | 0 | main.rs:10:34:10:38 | value | format argument |
| main.rs:10:25:10:25 | 1 | main.rs:10:41:10:45 | width | format argument |
| main.rs:10:28:10:28 | 2 | main.rs:10:48:10:56 | precision | format argument |
| main.rs:10:34:10:38 | value | main.rs:8:9:8:13 | value | local variable |
| main.rs:10:41:10:45 | width | main.rs:6:9:6:13 | width | local variable |
| main.rs:10:48:10:56 | precision | main.rs:7:9:7:17 | precision | local variable |
| main.rs:11:21:11:22 | {} | main.rs:11:29:11:33 | value | format argument |
| main.rs:11:24:11:25 | {} | main.rs:11:36:11:40 | width | format argument |
| main.rs:11:29:11:33 | value | main.rs:8:9:8:13 | value | local variable |
| main.rs:11:36:11:40 | width | main.rs:6:9:6:13 | width | local variable |
| main.rs:13:22:13:27 | people | main.rs:12:9:12:14 | people | local variable |
| main.rs:14:16:14:16 | 1 | main.rs:14:34:14:34 | 2 | format argument |
| main.rs:14:19:14:20 | {} | main.rs:14:31:14:31 | 1 | format argument |
| main.rs:14:23:14:23 | 0 | main.rs:14:31:14:31 | 1 | format argument |
| main.rs:14:26:14:27 | {} | main.rs:14:34:14:34 | 2 | format argument |
| main.rs:15:31:15:35 | {:<5} | main.rs:15:40:15:42 | "x" | format argument |
| main.rs:16:13:16:13 | S | main.rs:1:1:1:9 | struct S | path |
| main.rs:9:14:9:14 | S | main.rs:7:9:7:21 | struct S | path |
| main.rs:10:36:10:39 | Self | main.rs:7:9:7:21 | struct S | path |
| main.rs:11:17:11:17 | S | main.rs:7:9:7:21 | struct S | path |
| main.rs:21:22:21:26 | value | main.rs:21:50:21:54 | value | format argument |
| main.rs:21:29:21:33 | width | main.rs:18:9:18:13 | width | local variable |
| main.rs:21:36:21:44 | precision | main.rs:19:9:19:17 | precision | local variable |
| main.rs:22:22:22:22 | 0 | main.rs:22:34:22:38 | value | format argument |
| main.rs:22:25:22:25 | 1 | main.rs:22:41:22:45 | width | format argument |
| main.rs:22:28:22:28 | 2 | main.rs:22:48:22:56 | precision | format argument |
| main.rs:22:34:22:38 | value | main.rs:20:9:20:13 | value | local variable |
| main.rs:22:41:22:45 | width | main.rs:18:9:18:13 | width | local variable |
| main.rs:22:48:22:56 | precision | main.rs:19:9:19:17 | precision | local variable |
| main.rs:23:21:23:22 | {} | main.rs:23:29:23:33 | value | format argument |
| main.rs:23:24:23:25 | {} | main.rs:23:36:23:40 | width | format argument |
| main.rs:23:29:23:33 | value | main.rs:20:9:20:13 | value | local variable |
| main.rs:23:36:23:40 | width | main.rs:18:9:18:13 | width | local variable |
| main.rs:25:22:25:27 | people | main.rs:24:9:24:14 | people | local variable |
| main.rs:26:16:26:16 | 1 | main.rs:26:34:26:34 | 2 | format argument |
| main.rs:26:19:26:20 | {} | main.rs:26:31:26:31 | 1 | format argument |
| main.rs:26:23:26:23 | 0 | main.rs:26:31:26:31 | 1 | format argument |
| main.rs:26:26:26:27 | {} | main.rs:26:34:26:34 | 2 | format argument |
| main.rs:27:31:27:35 | {:<5} | main.rs:27:40:27:42 | "x" | format argument |
| main.rs:28:13:28:13 | S | main.rs:1:1:1:9 | struct S | path |
| main.rs:29:13:29:14 | M1 | main.rs:5:1:15:1 | mod M1 | path |
| main.rs:29:17:29:18 | M2 | main.rs:6:5:14:5 | mod M2 | path |
| main.rs:29:21:29:21 | S | main.rs:7:9:7:21 | struct S | path |
| main.rs:30:5:30:5 | s | main.rs:29:9:29:9 | s | local variable |
| main.rs:30:7:30:12 | method | main.rs:10:13:12:13 | fn method | method |
14 changes: 14 additions & 0 deletions rust/ql/test/library-tests/definitions/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ struct S;

mod lib;

mod M1 {
pub mod M2 {
pub struct S;

impl S {
pub fn method(self) -> Self {
S
}
}
}
}

fn main() {
let width = 4;
let precision = 2;
Expand All @@ -14,4 +26,6 @@ fn main() {
println!("{1} {} {0} {}", 1, 2);
assert_eq!(format!("Hello {:<5}!", "x"), "Hello x !");
let x = S;
let s = M1::M2::S;
s.method();
}