From 5cd729545d5e3dbd7e8360dd4c9b23b5771bb854 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 18 Jun 2025 09:22:32 +0200 Subject: [PATCH] Rust: Extend jump-to-def query with method calls --- .../lib/codeql/rust/internal/Definitions.qll | 26 +++++++++- .../definitions/Definitions.expected | 48 +++++++++++-------- .../ql/test/library-tests/definitions/main.rs | 14 ++++++ 3 files changed, 66 insertions(+), 22 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/Definitions.qll b/rust/ql/lib/codeql/rust/internal/Definitions.qll index 0603146c9af2..c03ece9d56de 100644 --- a/rust/ql/lib/codeql/rust/internal/Definitions.qll +++ b/rust/ql/lib/codeql/rust/internal/Definitions.qll @@ -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 + 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 | diff --git a/rust/ql/test/library-tests/definitions/Definitions.expected b/rust/ql/test/library-tests/definitions/Definitions.expected index 5d2a0db46c55..f3cde8950682 100644 --- a/rust/ql/test/library-tests/definitions/Definitions.expected +++ b/rust/ql/test/library-tests/definitions/Definitions.expected @@ -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 | diff --git a/rust/ql/test/library-tests/definitions/main.rs b/rust/ql/test/library-tests/definitions/main.rs index bde0b8cb993b..35acea6858e6 100644 --- a/rust/ql/test/library-tests/definitions/main.rs +++ b/rust/ql/test/library-tests/definitions/main.rs @@ -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; @@ -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(); }