From a0c6df3c1e29e9a3a46247696913a08752af5932 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 25 Apr 2025 14:27:37 +0200 Subject: [PATCH 1/2] Rust: Add another type inference test --- .../PathResolutionConsistency.expected | 3 ++ .../test/library-tests/type-inference/main.rs | 28 +++++++++++++++++++ .../type-inference/type-inference.expected | 19 ++++++++++--- 3 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected diff --git a/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected new file mode 100644 index 000000000000..227d8789153f --- /dev/null +++ b/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected @@ -0,0 +1,3 @@ +multipleMethodCallTargets +| main.rs:945:26:945:31 | x.m1() | main.rs:931:9:933:9 | fn m1 | +| main.rs:945:26:945:31 | x.m1() | main.rs:938:9:940:9 | fn m1 | diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index 1972b181c83c..87ef61eede9b 100644 --- a/rust/ql/test/library-tests/type-inference/main.rs +++ b/rust/ql/test/library-tests/type-inference/main.rs @@ -919,6 +919,33 @@ mod borrowed_typed { } } +mod impl_overlap { + #[derive(Debug)] + struct S1; + + trait MyTrait { + fn m1(self) -> S1; + } + + impl MyTrait for S1 { + fn m1(self) -> S1 { + panic!("not called"); + } + } + + #[rustfmt::skip] + impl S1 { + fn m1(self) -> S1 { // target + self + } + } + + pub fn f() { + let x = S1; + println!("{:?}", x.m1()); // $ method=target + } +} + fn main() { field_access::f(); method_impl::f(); @@ -935,4 +962,5 @@ fn main() { trait_implicit_self_borrow::f(); implicit_self_borrow::f(); borrowed_typed::f(); + impl_overlap::f(); } diff --git a/rust/ql/test/library-tests/type-inference/type-inference.expected b/rust/ql/test/library-tests/type-inference/type-inference.expected index c91b3cef3dc3..4f62e0a04058 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -1,4 +1,5 @@ testFailures +| main.rs:945:26:945:31 | x.m1() | Unexpected result: method=m1 | inferType | loop/main.rs:7:12:7:15 | SelfParam | | loop/main.rs:6:1:8:1 | Self [trait T1] | | loop/main.rs:11:12:11:15 | SelfParam | | loop/main.rs:10:1:14:1 | Self [trait T2] | @@ -1005,7 +1006,17 @@ inferType | main.rs:918:15:918:16 | &x | | file://:0:0:0:0 | & | | main.rs:918:15:918:16 | &x | &T | main.rs:894:5:894:13 | S | | main.rs:918:16:918:16 | x | | main.rs:894:5:894:13 | S | -| main.rs:924:5:924:20 | ...::f(...) | | main.rs:67:5:67:21 | Foo | -| main.rs:925:5:925:60 | ...::g(...) | | main.rs:67:5:67:21 | Foo | -| main.rs:925:20:925:38 | ...::Foo {...} | | main.rs:67:5:67:21 | Foo | -| main.rs:925:41:925:59 | ...::Foo {...} | | main.rs:67:5:67:21 | Foo | +| main.rs:927:15:927:18 | SelfParam | | main.rs:926:5:928:5 | Self [trait MyTrait] | +| main.rs:931:15:931:18 | SelfParam | | main.rs:923:5:924:14 | S1 | +| main.rs:931:27:933:9 | { ... } | | main.rs:923:5:924:14 | S1 | +| main.rs:938:15:938:18 | SelfParam | | main.rs:923:5:924:14 | S1 | +| main.rs:938:27:940:9 | { ... } | | main.rs:923:5:924:14 | S1 | +| main.rs:939:13:939:16 | self | | main.rs:923:5:924:14 | S1 | +| main.rs:944:13:944:13 | x | | main.rs:923:5:924:14 | S1 | +| main.rs:944:17:944:18 | S1 | | main.rs:923:5:924:14 | S1 | +| main.rs:945:26:945:26 | x | | main.rs:923:5:924:14 | S1 | +| main.rs:945:26:945:31 | x.m1() | | main.rs:923:5:924:14 | S1 | +| main.rs:951:5:951:20 | ...::f(...) | | main.rs:67:5:67:21 | Foo | +| main.rs:952:5:952:60 | ...::g(...) | | main.rs:67:5:67:21 | Foo | +| main.rs:952:20:952:38 | ...::Foo {...} | | main.rs:67:5:67:21 | Foo | +| main.rs:952:41:952:59 | ...::Foo {...} | | main.rs:67:5:67:21 | Foo | From 6599a2eef8de4f3404bfb05466a5369995e4647d Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 25 Apr 2025 14:48:08 +0200 Subject: [PATCH 2/2] Rust: Model `impl` shadowing --- rust/ql/lib/codeql/rust/internal/Type.qll | 20 +++++++++++++++++-- .../PathResolutionConsistency.expected | 3 --- .../PathResolutionConsistency.expected | 3 --- .../PathResolutionConsistency.expected | 3 --- .../type-inference/type-inference.expected | 1 - 5 files changed, 18 insertions(+), 12 deletions(-) delete mode 100644 rust/ql/test/extractor-tests/canonical_path/CONSISTENCY/PathResolutionConsistency.expected delete mode 100644 rust/ql/test/extractor-tests/canonical_path_disabled/CONSISTENCY/PathResolutionConsistency.expected delete mode 100644 rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected diff --git a/rust/ql/lib/codeql/rust/internal/Type.qll b/rust/ql/lib/codeql/rust/internal/Type.qll index 9e063d215161..b99a6b7838be 100644 --- a/rust/ql/lib/codeql/rust/internal/Type.qll +++ b/rust/ql/lib/codeql/rust/internal/Type.qll @@ -74,15 +74,31 @@ abstract class Type extends TType { abstract private class StructOrEnumType extends Type { abstract ItemNode asItemNode(); - final override Function getMethod(string name) { + pragma[nomagic] + private Function getMethodCand(ImplOrTraitItemNode impl, string name) { result = this.asItemNode().getASuccessor(name) and - exists(ImplOrTraitItemNode impl | result = impl.getAnAssocItem() | + result = impl.getAnAssocItem() and + ( impl instanceof Trait or impl.(ImplItemNode).isFullyParametric() ) } + pragma[nomagic] + private Function getImplMethod(ImplOrTraitItemNode impl, string name) { + result = this.getMethodCand(impl, name) and + impl = any(Impl i | not i.hasTrait()) + } + + final override Function getMethod(string name) { + result = this.getImplMethod(_, name) + or + // methods from `impl` blocks shadow functions from `impl Trait` blocks + result = this.getMethodCand(_, name) and + not exists(this.getImplMethod(_, name)) + } + /** Gets all of the fully parametric `impl` blocks that target this type. */ final override ImplMention getABaseTypeMention() { this.asItemNode() = result.resolveSelfTy() and diff --git a/rust/ql/test/extractor-tests/canonical_path/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/extractor-tests/canonical_path/CONSISTENCY/PathResolutionConsistency.expected deleted file mode 100644 index fbc771e88519..000000000000 --- a/rust/ql/test/extractor-tests/canonical_path/CONSISTENCY/PathResolutionConsistency.expected +++ /dev/null @@ -1,3 +0,0 @@ -multipleMethodCallTargets -| regular.rs:29:5:29:9 | s.g() | anonymous.rs:15:9:15:22 | fn g | -| regular.rs:29:5:29:9 | s.g() | regular.rs:13:5:13:18 | fn g | diff --git a/rust/ql/test/extractor-tests/canonical_path_disabled/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/extractor-tests/canonical_path_disabled/CONSISTENCY/PathResolutionConsistency.expected deleted file mode 100644 index 849d19acbf0e..000000000000 --- a/rust/ql/test/extractor-tests/canonical_path_disabled/CONSISTENCY/PathResolutionConsistency.expected +++ /dev/null @@ -1,3 +0,0 @@ -multipleMethodCallTargets -| regular.rs:32:5:32:9 | s.g() | anonymous.rs:18:9:18:22 | fn g | -| regular.rs:32:5:32:9 | s.g() | regular.rs:16:5:16:18 | fn g | diff --git a/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected deleted file mode 100644 index 227d8789153f..000000000000 --- a/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected +++ /dev/null @@ -1,3 +0,0 @@ -multipleMethodCallTargets -| main.rs:945:26:945:31 | x.m1() | main.rs:931:9:933:9 | fn m1 | -| main.rs:945:26:945:31 | x.m1() | main.rs:938:9:940:9 | fn m1 | diff --git a/rust/ql/test/library-tests/type-inference/type-inference.expected b/rust/ql/test/library-tests/type-inference/type-inference.expected index 4f62e0a04058..a8bfdfa1aebf 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -1,5 +1,4 @@ testFailures -| main.rs:945:26:945:31 | x.m1() | Unexpected result: method=m1 | inferType | loop/main.rs:7:12:7:15 | SelfParam | | loop/main.rs:6:1:8:1 | Self [trait T1] | | loop/main.rs:11:12:11:15 | SelfParam | | loop/main.rs:10:1:14:1 | Self [trait T2] |