Content-Length: 409158 | pFad | http://github.com/github/codeql/pull/20096.patch
thub.com
From 71a5e410d7c3eca9551e444d8811b64cc675ce98 Mon Sep 17 00:00:00 2001
From: Simon Friis Vindum
Date: Mon, 21 Jul 2025 09:46:23 +0200
Subject: [PATCH 1/4] Rust: Add path resolution test
---
.../library-tests/path-resolution/main.rs | 54 +++++
.../path-resolution/path-resolution.expected | 188 +++++++++++-------
2 files changed, 170 insertions(+), 72 deletions(-)
diff --git a/rust/ql/test/library-tests/path-resolution/main.rs b/rust/ql/test/library-tests/path-resolution/main.rs
index cf848ba26876..0fe50494d2d9 100644
--- a/rust/ql/test/library-tests/path-resolution/main.rs
+++ b/rust/ql/test/library-tests/path-resolution/main.rs
@@ -636,6 +636,60 @@ impl AStruct // $ item=I123
pub fn z(&self) {} // I125
}
+mod associated_types {
+ use std::marker::PhantomData; // $ item=PhantomData
+ use std::result::Result; // $ item=Result
+
+ trait Reduce {
+ type Input; // ReduceInput
+ type Error; // ReduceError
+ type Output; // ReduceOutput
+ fn feed(
+ &mut self,
+ item: Self::Input, // $ item=ReduceInput
+ ) -> Result; // $ item=Result item=ReduceOutput item=ReduceError
+ } // IReduce
+
+ struct MyImpl {
+ _input: PhantomData, // $ item=PhantomData item=Input
+ _error: PhantomData, // $ item=PhantomData item=Error
+ } // MyImpl
+
+ #[rustfmt::skip]
+ impl<
+ Input, // IInput
+ Error, // IError
+ > Reduce // $ item=IReduce
+ for MyImpl<
+ Input, // $ item=IInput SPURIOUS: item=IInputAssociated
+ Error, // $ item=IError SPURIOUS: item=IErrorAssociated
+ > // $ item=MyImpl
+ {
+ type Input = Result<
+ Input, // $ item=IInput SPURIOUS: item=IInputAssociated
+ Self::Error, // $ item=IErrorAssociated SPURIOUS: item=IError
+ > // $ item=Result
+ ; // IInputAssociated
+ type Error = Option<
+ Error // $ item=IError SPURIOUS: item=IErrorAssociated
+ > // $ item=Option
+ ; // IErrorAssociated
+ type Output =
+ Input // $ item=IInput SPURIOUS: item=IInputAssociated
+ ; // IOutputAssociated
+
+ fn feed(
+ &mut self,
+ item: Self::Input // $ item=IInputAssociated SPURIOUS: item=IInput
+ ) -> Result<
+ Self::Output, // $ item=IOutputAssociated
+ Self::Error // $ item=IErrorAssociated SPURIOUS: item=IError
+ > { // $ item=Result
+ item
+ }
+ }
+}
+
use std::{self as ztd}; // $ item=std
fn use_ztd(x: ztd::string::String) {} // $ item=String
diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.expected b/rust/ql/test/library-tests/path-resolution/path-resolution.expected
index c757e29396f7..c0d36d0565d7 100644
--- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected
+++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected
@@ -28,6 +28,7 @@ mod
| main.rs:509:5:524:5 | mod m33 |
| main.rs:527:1:552:1 | mod m23 |
| main.rs:554:1:622:1 | mod m24 |
+| main.rs:639:1:691:1 | mod associated_types |
| my2/mod.rs:1:1:1:16 | mod nested2 |
| my2/mod.rs:12:1:12:12 | mod my3 |
| my2/mod.rs:14:1:15:10 | mod mymod |
@@ -61,7 +62,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:677:2 | SourceFile |
+| main.rs:40:9:40:13 | super | main.rs:1:1:731: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 +74,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:677:2 | SourceFile |
+| main.rs:68:5:68:8 | self | main.rs:1:1:731: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 +89,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:677:2 | SourceFile |
+| main.rs:117:13:117:17 | super | main.rs:1:1:731: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 |
@@ -276,74 +277,117 @@ resolvePath
| 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 |
+| main.rs:640:9:640:11 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) |
+| main.rs:640:9:640:19 | ...::marker | {EXTERNAL LOCATION} | mod marker |
+| main.rs:640:9:640:32 | ...::PhantomData | {EXTERNAL LOCATION} | struct PhantomData |
+| main.rs:641:9:641:11 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) |
+| main.rs:641:9:641:19 | ...::result | {EXTERNAL LOCATION} | mod result |
+| main.rs:641:9:641:27 | ...::Result | {EXTERNAL LOCATION} | enum Result |
+| main.rs:649:19:649:22 | Self | main.rs:643:5:651:5 | trait Reduce |
+| main.rs:649:19:649:29 | ...::Input | main.rs:644:9:644:19 | type Input |
+| main.rs:650:14:650:46 | Result::<...> | {EXTERNAL LOCATION} | enum Result |
+| main.rs:650:21:650:24 | Self | main.rs:643:5:651:5 | trait Reduce |
+| main.rs:650:21:650:32 | ...::Output | main.rs:645:21:646:20 | type Output |
+| main.rs:650:35:650:38 | Self | main.rs:643:5:651:5 | trait Reduce |
+| main.rs:650:35:650:45 | ...::Error | main.rs:644:21:645:19 | type Error |
+| main.rs:654:17:654:34 | PhantomData::<...> | {EXTERNAL LOCATION} | struct PhantomData |
+| main.rs:654:29:654:33 | Input | main.rs:653:19:653:23 | Input |
+| main.rs:655:17:655:34 | PhantomData::<...> | {EXTERNAL LOCATION} | struct PhantomData |
+| main.rs:655:29:655:33 | Error | main.rs:653:26:653:30 | Error |
+| main.rs:662:11:662:16 | Reduce | main.rs:643:5:651:5 | trait Reduce |
+| main.rs:663:13:666:9 | MyImpl::<...> | main.rs:653:5:656:5 | struct MyImpl |
+| main.rs:664:13:664:17 | Input | main.rs:660:13:660:17 | Input |
+| main.rs:664:13:664:17 | Input | main.rs:668:9:672:9 | type Input |
+| main.rs:665:13:665:17 | Error | main.rs:661:13:661:17 | Error |
+| main.rs:665:13:665:17 | Error | main.rs:672:11:676:9 | type Error |
+| main.rs:668:22:671:9 | Result::<...> | {EXTERNAL LOCATION} | enum Result |
+| main.rs:669:13:669:17 | Input | main.rs:660:13:660:17 | Input |
+| main.rs:669:13:669:17 | Input | main.rs:668:9:672:9 | type Input |
+| main.rs:670:13:670:16 | Self | main.rs:658:5:690:5 | impl Reduce for MyImpl::<...> { ... } |
+| main.rs:670:13:670:23 | ...::Error | main.rs:661:13:661:17 | Error |
+| main.rs:670:13:670:23 | ...::Error | main.rs:672:11:676:9 | type Error |
+| main.rs:673:22:675:9 | Option::<...> | {EXTERNAL LOCATION} | enum Option |
+| main.rs:674:11:674:15 | Error | main.rs:661:13:661:17 | Error |
+| main.rs:674:11:674:15 | Error | main.rs:672:11:676:9 | type Error |
+| main.rs:678:13:678:17 | Input | main.rs:660:13:660:17 | Input |
+| main.rs:678:13:678:17 | Input | main.rs:668:9:672:9 | type Input |
+| main.rs:683:19:683:22 | Self | main.rs:658:5:690:5 | impl Reduce for MyImpl::<...> { ... } |
+| main.rs:683:19:683:29 | ...::Input | main.rs:660:13:660:17 | Input |
+| main.rs:683:19:683:29 | ...::Input | main.rs:668:9:672:9 | type Input |
+| main.rs:684:14:687:9 | Result::<...> | {EXTERNAL LOCATION} | enum Result |
+| main.rs:685:13:685:16 | Self | main.rs:658:5:690:5 | impl Reduce for MyImpl::<...> { ... } |
+| main.rs:685:13:685:24 | ...::Output | main.rs:676:11:679:9 | type Output |
+| main.rs:686:13:686:16 | Self | main.rs:658:5:690:5 | impl Reduce for MyImpl::<...> { ... } |
+| main.rs:686:13:686:23 | ...::Error | main.rs:661:13:661:17 | Error |
+| main.rs:686:13:686:23 | ...::Error | main.rs:672:11:676:9 | type Error |
+| main.rs:693:5:693:7 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) |
+| main.rs:693:11:693:14 | self | {EXTERNAL LOCATION} | Crate(std@0.0.0) |
+| main.rs:695:15:695:17 | ztd | {EXTERNAL LOCATION} | Crate(std@0.0.0) |
+| main.rs:695:15:695:25 | ...::string | {EXTERNAL LOCATION} | mod string |
+| main.rs:695:15:695:33 | ...::String | {EXTERNAL LOCATION} | struct String |
+| main.rs:698:5:698:6 | my | main.rs:1:1:1:7 | mod my |
+| main.rs:698:5:698:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
+| main.rs:698:5:698:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |
+| main.rs:698:5:698:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 |
+| main.rs:698:5:698:35 | ...::f | my/nested.rs:3:9:5:9 | fn f |
+| main.rs:699:5:699:6 | my | main.rs:1:1:1:7 | mod my |
+| main.rs:699:5:699:9 | ...::f | my.rs:5:1:7:1 | fn f |
+| main.rs:700:5:700:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 |
+| main.rs:700:5:700:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 |
+| main.rs:700:5:700:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 |
+| main.rs:700:5:700:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f |
+| main.rs:701:5:701:5 | f | my2/nested2.rs:3:9:5:9 | fn f |
+| main.rs:702:5:702:5 | g | my2/nested2.rs:7:9:9:9 | fn g |
+| main.rs:703:5:703:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) |
+| main.rs:703:5:703:12 | ...::h | main.rs:50:1:69:1 | fn h |
+| main.rs:704:5:704:6 | m1 | main.rs:13:1:37:1 | mod m1 |
+| main.rs:704:5:704:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 |
+| main.rs:704:5:704:13 | ...::g | main.rs:23:9:27:9 | fn g |
+| main.rs:705:5:705:6 | m1 | main.rs:13:1:37:1 | mod m1 |
+| main.rs:705:5:705:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 |
+| main.rs:705:5:705:14 | ...::m3 | main.rs:29:9:35:9 | mod m3 |
+| main.rs:705:5:705:17 | ...::h | main.rs:30:27:34:13 | fn h |
+| main.rs:706:5:706:6 | m4 | main.rs:39:1:46:1 | mod m4 |
+| main.rs:706:5:706:9 | ...::i | main.rs:42:5:45:5 | fn i |
+| main.rs:707:5:707:5 | h | main.rs:50:1:69:1 | fn h |
+| main.rs:708:5:708:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f |
+| main.rs:709:5:709:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g |
+| main.rs:710:5:710:5 | j | main.rs:97:1:101:1 | fn j |
+| main.rs:711:5:711:6 | m6 | main.rs:109:1:120:1 | mod m6 |
+| main.rs:711:5:711:9 | ...::g | main.rs:114:5:119:5 | fn g |
+| main.rs:712:5:712:6 | m7 | main.rs:122:1:141:1 | mod m7 |
+| main.rs:712:5:712:9 | ...::f | main.rs:133:5:140:5 | fn f |
+| main.rs:713:5:713:6 | m8 | main.rs:143:1:197:1 | mod m8 |
+| main.rs:713:5:713:9 | ...::g | main.rs:181:5:196:5 | fn g |
+| main.rs:714:5:714:6 | m9 | main.rs:199:1:207:1 | mod m9 |
+| main.rs:714:5:714:9 | ...::f | main.rs:202:5:206:5 | fn f |
+| main.rs:715:5:715:7 | m11 | main.rs:230:1:267:1 | mod m11 |
+| main.rs:715:5:715:10 | ...::f | main.rs:235:5:238:5 | fn f |
+| main.rs:716:5:716:7 | m15 | main.rs:298:1:352:1 | mod m15 |
+| main.rs:716:5:716:10 | ...::f | main.rs:339:5:351:5 | fn f |
+| main.rs:717:5:717:7 | m16 | main.rs:354:1:446:1 | mod m16 |
+| main.rs:717:5:717:10 | ...::f | main.rs:421:5:445:5 | fn f |
+| main.rs:718:5:718:7 | m17 | main.rs:448:1:478:1 | mod m17 |
+| main.rs:718:5:718:10 | ...::f | main.rs:472:5:477:5 | fn f |
+| main.rs:719:5:719:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 |
+| main.rs:719:5:719:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f |
+| main.rs:720:5:720:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 |
+| main.rs:720:5:720:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f |
+| main.rs:721:5:721:7 | my3 | my2/mod.rs:12:1:12:12 | mod my3 |
+| main.rs:721:5:721:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f |
+| main.rs:722:5:722:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
+| main.rs:723:5:723:7 | m18 | main.rs:480:1:498:1 | mod m18 |
+| main.rs:723:5:723:12 | ...::m19 | main.rs:485:5:497:5 | mod m19 |
+| main.rs:723:5:723:17 | ...::m20 | main.rs:490:9:496:9 | mod m20 |
+| main.rs:723:5:723:20 | ...::g | main.rs:491:13:495:13 | fn g |
+| main.rs:724:5:724:7 | m23 | main.rs:527:1:552:1 | mod m23 |
+| main.rs:724:5:724:10 | ...::f | main.rs:547:5:551:5 | fn f |
+| main.rs:725:5:725:7 | m24 | main.rs:554:1:622:1 | mod m24 |
+| main.rs:725:5:725:10 | ...::f | main.rs:608:5:621:5 | fn f |
+| main.rs:726:5:726:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) |
+| main.rs:726:5:726:11 | ...::h | main.rs:50:1:69:1 | fn h |
+| main.rs:728:5:728:11 | AStruct | main.rs:629:1:629:17 | struct AStruct |
+| main.rs:729:5:729: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 |
@@ -359,7 +403,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:677:2 | SourceFile |
+| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:731: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 |
From ac6715fb3a08f18cd5650e6496d57e423271e2c7 Mon Sep 17 00:00:00 2001
From: Simon Friis Vindum
Date: Mon, 21 Jul 2025 10:01:00 +0200
Subject: [PATCH 2/4] Rust: Avoid mixing up type parameters and associated
types in path resolution
---
.../codeql/rust/internal/PathResolution.qll | 104 +++++++++++-------
.../library-tests/path-resolution/main.rs | 16 +--
.../path-resolution/path-resolution.expected | 8 --
.../test/library-tests/type-inference/main.rs | 2 +-
.../type-inference/type-inference.expected | 18 +--
5 files changed, 79 insertions(+), 69 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll
index 33cfb6c0d7bf..f9097ee39657 100644
--- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll
+++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll
@@ -112,13 +112,18 @@ abstract class ItemNode extends Locatable {
result = this.(SourceFileItemNode).getSuper()
}
+ pragma[nomagic]
+ private ItemNode getAChildSuccessor(string name) {
+ this = result.getImmediateParent() and
+ name = result.getName()
+ }
+
cached
ItemNode getASuccessorRec(string name) {
Stages::PathResolutionStage::ref() and
sourceFileEdge(this, name, result)
or
- this = result.getImmediateParent() and
- name = result.getName()
+ result = this.getAChildSuccessor(name)
or
fileImportEdge(this, name, result)
or
@@ -224,6 +229,38 @@ abstract class ItemNode extends Locatable {
result.(CrateItemNode).isPotentialDollarCrateTarget()
}
+ /**
+ * Holds if the successor `item` with the name `name` is not available locally
+ * for unqualified paths.
+ *
+ * This has the effect that a path of the form `name` inside `this` will not
+ * resolve to `item`.
+ */
+ pragma[nomagic]
+ predicate excludedLocally(string name, ItemNode item) {
+ // Associated items in an impl or trait block are not directly available
+ // inside the block, they require a qualified path with a `Self` prefix.
+ item = this.getAChildSuccessor(name) and
+ this instanceof ImplOrTraitItemNode and
+ item instanceof AssocItemNode
+ }
+
+ /**
+ * Holds if the successor `item` with the name `name` is not available
+ * externally for qualified paths that resolve to this item.
+ *
+ * This has the effect that a path of the form `Qualifier::name`, where
+ * `Qualifier` resolves to this item, will not resolve to `item`.
+ */
+ pragma[nomagic]
+ predicate excludedExternally(string name, ItemNode item) {
+ // Type parameters for an `impl` or trait block are not available outside of
+ // the block.
+ item = this.getAChildSuccessor(name) and
+ this instanceof ImplOrTraitItemNode and
+ item instanceof TypeParamItemNode
+ }
+
pragma[nomagic]
private predicate hasSourceFunction(string name) {
this.getASuccessorFull(name).(Function).fromSource()
@@ -1145,7 +1182,9 @@ pragma[nomagic]
private predicate declares(ItemNode item, Namespace ns, string name) {
exists(ItemNode child | child.getImmediateParent() = item |
child.getName() = name and
- child.getNamespace() = ns
+ child.getNamespace() = ns and
+ // If `item` is excluded locally then it does not declare `name`.
+ not item.excludedLocally(name, child)
or
useTreeDeclares(child.(Use).getUseTree(), name) and
exists(ns) // `use foo::bar` can refer to both a value and a type
@@ -1193,38 +1232,27 @@ private ItemNode getOuterScope(ItemNode i) {
result = i.getImmediateParent()
}
-pragma[nomagic]
-private ItemNode getAdjustedEnclosing(ItemNode encl0, Namespace ns) {
- // functions in `impl` blocks need to use explicit `Self::` to access other
- // functions in the `impl` block
- if encl0 instanceof ImplOrTraitItemNode and ns.isValue()
- then result = encl0.getImmediateParent()
- else result = encl0
-}
-
/**
* Holds if the unqualified path `p` references an item named `name`, and `name`
* may be looked up in the `ns` namespace inside enclosing item `encl`.
*/
pragma[nomagic]
private predicate unqualifiedPathLookup(ItemNode encl, string name, Namespace ns, RelevantPath p) {
- exists(ItemNode encl0 | encl = getAdjustedEnclosing(encl0, ns) |
- // lookup in the immediately enclosing item
- p.isUnqualified(name) and
- encl0.getADescendant() = p and
- exists(ns) and
- not name = ["crate", "$crate", "super", "self"]
- or
- // lookup in an outer scope, but only if the item is not declared in inner scope
- exists(ItemNode mid |
- unqualifiedPathLookup(mid, name, ns, p) and
- not declares(mid, ns, name) and
- not (
- name = "Self" and
- mid = any(ImplOrTraitItemNode i).getAnItemInSelfScope()
- ) and
- encl0 = getOuterScope(mid)
- )
+ // lookup in the immediately enclosing item
+ p.isUnqualified(name) and
+ encl.getADescendant() = p and
+ exists(ns) and
+ not name = ["crate", "$crate", "super", "self"]
+ or
+ // lookup in an outer scope, but only if the item is not declared in inner scope
+ exists(ItemNode mid |
+ unqualifiedPathLookup(mid, name, ns, p) and
+ not declares(mid, ns, name) and
+ not (
+ name = "Self" and
+ mid = any(ImplOrTraitItemNode i).getAnItemInSelfScope()
+ ) and
+ encl = getOuterScope(mid)
)
}
@@ -1245,10 +1273,10 @@ private predicate sourceFileHasCratePathTc(ItemNode i1, ItemNode i2) =
/**
* Holds if the unqualified path `p` references a keyword item named `name`, and
- * `name` may be looked up in the `ns` namespace inside enclosing item `encl`.
+ * `name` may be looked up inside enclosing item `encl`.
*/
pragma[nomagic]
-private predicate keywordLookup(ItemNode encl, string name, Namespace ns, RelevantPath p) {
+private predicate keywordLookup(ItemNode encl, string name, RelevantPath p) {
// For `($)crate`, jump directly to the root module
exists(ItemNode i | p.isCratePath(name, i) |
encl instanceof SourceFile and
@@ -1259,18 +1287,17 @@ private predicate keywordLookup(ItemNode encl, string name, Namespace ns, Releva
or
name = ["super", "self"] and
p.isUnqualified(name) and
- exists(ItemNode encl0 |
- encl0.getADescendant() = p and
- encl = getAdjustedEnclosing(encl0, ns)
- )
+ encl.getADescendant() = p
}
pragma[nomagic]
private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns) {
- exists(ItemNode encl, string name | result = getASuccessorFull(encl, name, ns) |
+ exists(ItemNode encl, string name |
+ result = getASuccessorFull(encl, name, ns) and not encl.excludedLocally(name, result)
+ |
unqualifiedPathLookup(encl, name, ns, p)
or
- keywordLookup(encl, name, ns, p)
+ keywordLookup(encl, name, p) and exists(ns)
)
}
@@ -1291,7 +1318,8 @@ private ItemNode resolvePath0(RelevantPath path, Namespace ns) {
or
exists(ItemNode q, string name |
q = resolvePathQualifier(path, name) and
- result = getASuccessorFull(q, name, ns)
+ result = getASuccessorFull(q, name, ns) and
+ not q.excludedExternally(name, result)
)
or
result = resolveUseTreeListItem(_, _, path) and
diff --git a/rust/ql/test/library-tests/path-resolution/main.rs b/rust/ql/test/library-tests/path-resolution/main.rs
index 0fe50494d2d9..cfac46c144fc 100644
--- a/rust/ql/test/library-tests/path-resolution/main.rs
+++ b/rust/ql/test/library-tests/path-resolution/main.rs
@@ -661,29 +661,29 @@ mod associated_types {
Error, // IError
> Reduce // $ item=IReduce
for MyImpl<
- Input, // $ item=IInput SPURIOUS: item=IInputAssociated
- Error, // $ item=IError SPURIOUS: item=IErrorAssociated
+ Input, // $ item=IInput
+ Error, // $ item=IError
> // $ item=MyImpl
{
type Input = Result<
- Input, // $ item=IInput SPURIOUS: item=IInputAssociated
- Self::Error, // $ item=IErrorAssociated SPURIOUS: item=IError
+ Input, // $ item=IInput
+ Self::Error, // $ item=IErrorAssociated
> // $ item=Result
; // IInputAssociated
type Error = Option<
- Error // $ item=IError SPURIOUS: item=IErrorAssociated
+ Error // $ item=IError
> // $ item=Option
; // IErrorAssociated
type Output =
- Input // $ item=IInput SPURIOUS: item=IInputAssociated
+ Input // $ item=IInput
; // IOutputAssociated
fn feed(
&mut self,
- item: Self::Input // $ item=IInputAssociated SPURIOUS: item=IInput
+ item: Self::Input // $ item=IInputAssociated
) -> Result<
Self::Output, // $ item=IOutputAssociated
- Self::Error // $ item=IErrorAssociated SPURIOUS: item=IError
+ Self::Error // $ item=IErrorAssociated
> { // $ item=Result
item
}
diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.expected b/rust/ql/test/library-tests/path-resolution/path-resolution.expected
index c0d36d0565d7..99cb6f8168c3 100644
--- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected
+++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected
@@ -297,28 +297,20 @@ resolvePath
| main.rs:662:11:662:16 | Reduce | main.rs:643:5:651:5 | trait Reduce |
| main.rs:663:13:666:9 | MyImpl::<...> | main.rs:653:5:656:5 | struct MyImpl |
| main.rs:664:13:664:17 | Input | main.rs:660:13:660:17 | Input |
-| main.rs:664:13:664:17 | Input | main.rs:668:9:672:9 | type Input |
| main.rs:665:13:665:17 | Error | main.rs:661:13:661:17 | Error |
-| main.rs:665:13:665:17 | Error | main.rs:672:11:676:9 | type Error |
| main.rs:668:22:671:9 | Result::<...> | {EXTERNAL LOCATION} | enum Result |
| main.rs:669:13:669:17 | Input | main.rs:660:13:660:17 | Input |
-| main.rs:669:13:669:17 | Input | main.rs:668:9:672:9 | type Input |
| main.rs:670:13:670:16 | Self | main.rs:658:5:690:5 | impl Reduce for MyImpl::<...> { ... } |
-| main.rs:670:13:670:23 | ...::Error | main.rs:661:13:661:17 | Error |
| main.rs:670:13:670:23 | ...::Error | main.rs:672:11:676:9 | type Error |
| main.rs:673:22:675:9 | Option::<...> | {EXTERNAL LOCATION} | enum Option |
| main.rs:674:11:674:15 | Error | main.rs:661:13:661:17 | Error |
-| main.rs:674:11:674:15 | Error | main.rs:672:11:676:9 | type Error |
| main.rs:678:13:678:17 | Input | main.rs:660:13:660:17 | Input |
-| main.rs:678:13:678:17 | Input | main.rs:668:9:672:9 | type Input |
| main.rs:683:19:683:22 | Self | main.rs:658:5:690:5 | impl Reduce for MyImpl::<...> { ... } |
-| main.rs:683:19:683:29 | ...::Input | main.rs:660:13:660:17 | Input |
| main.rs:683:19:683:29 | ...::Input | main.rs:668:9:672:9 | type Input |
| main.rs:684:14:687:9 | Result::<...> | {EXTERNAL LOCATION} | enum Result |
| main.rs:685:13:685:16 | Self | main.rs:658:5:690:5 | impl Reduce for MyImpl::<...> { ... } |
| main.rs:685:13:685:24 | ...::Output | main.rs:676:11:679:9 | type Output |
| main.rs:686:13:686:16 | Self | main.rs:658:5:690:5 | impl Reduce for MyImpl::<...> { ... } |
-| main.rs:686:13:686:23 | ...::Error | main.rs:661:13:661:17 | Error |
| main.rs:686:13:686:23 | ...::Error | main.rs:672:11:676:9 | type Error |
| main.rs:693:5:693:7 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) |
| main.rs:693:11:693:14 | self | {EXTERNAL LOCATION} | Crate(std@0.0.0) |
diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs
index a4a37e27794c..b6a8fdca36ca 100644
--- a/rust/ql/test/library-tests/type-inference/main.rs
+++ b/rust/ql/test/library-tests/type-inference/main.rs
@@ -2162,7 +2162,7 @@ mod loops {
for i in [1, 2, 3] {} // $ type=i:i32
for i in [1, 2, 3].map(|x| x + 1) {} // $ target=map MISSING: type=i:i32
- for i in [1, 2, 3].into_iter() {} // $ target=into_iter MISSING: type=i:i32
+ for i in [1, 2, 3].into_iter() {} // $ target=into_iter type=i:i32
let vals1 = [1u8, 2, 3]; // $ type=vals1:[T;...].u8
for u in vals1 {} // $ type=u:u8
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 e4da3d0dd168..04df22c16041 100644
--- a/rust/ql/test/library-tests/type-inference/type-inference.expected
+++ b/rust/ql/test/library-tests/type-inference/type-inference.expected
@@ -3526,8 +3526,12 @@ inferType
| main.rs:2164:22:2164:22 | 2 | | {EXTERNAL LOCATION} | i32 |
| main.rs:2164:25:2164:25 | 3 | | {EXTERNAL LOCATION} | i32 |
| main.rs:2164:40:2164:40 | 1 | | {EXTERNAL LOCATION} | i32 |
+| main.rs:2165:13:2165:13 | i | | {EXTERNAL LOCATION} | Item |
+| main.rs:2165:13:2165:13 | i | | {EXTERNAL LOCATION} | i32 |
| main.rs:2165:18:2165:26 | [...] | | file://:0:0:0:0 | [] |
| main.rs:2165:18:2165:26 | [...] | [T;...] | {EXTERNAL LOCATION} | i32 |
+| main.rs:2165:18:2165:38 | ... .into_iter() | | {EXTERNAL LOCATION} | IntoIter |
+| main.rs:2165:18:2165:38 | ... .into_iter() | T | {EXTERNAL LOCATION} | i32 |
| main.rs:2165:19:2165:19 | 1 | | {EXTERNAL LOCATION} | i32 |
| main.rs:2165:22:2165:22 | 2 | | {EXTERNAL LOCATION} | i32 |
| main.rs:2165:25:2165:25 | 3 | | {EXTERNAL LOCATION} | i32 |
@@ -3739,11 +3743,8 @@ inferType
| main.rs:2226:39:2226:39 | 2 | | {EXTERNAL LOCATION} | u16 |
| main.rs:2226:42:2226:42 | 3 | | {EXTERNAL LOCATION} | i32 |
| main.rs:2226:42:2226:42 | 3 | | {EXTERNAL LOCATION} | u16 |
-| main.rs:2227:13:2227:13 | u | | {EXTERNAL LOCATION} | Vec |
| main.rs:2227:13:2227:13 | u | | {EXTERNAL LOCATION} | u16 |
| main.rs:2227:13:2227:13 | u | | file://:0:0:0:0 | & |
-| main.rs:2227:13:2227:13 | u | A | {EXTERNAL LOCATION} | Global |
-| main.rs:2227:13:2227:13 | u | T | {EXTERNAL LOCATION} | u16 |
| main.rs:2227:18:2227:23 | vals4a | | {EXTERNAL LOCATION} | Vec |
| main.rs:2227:18:2227:23 | vals4a | A | {EXTERNAL LOCATION} | Global |
| main.rs:2227:18:2227:23 | vals4a | T | {EXTERNAL LOCATION} | u16 |
@@ -3773,13 +3774,9 @@ inferType
| main.rs:2232:38:2232:38 | 2 | | {EXTERNAL LOCATION} | u32 |
| main.rs:2232:41:2232:41 | 3 | | {EXTERNAL LOCATION} | i32 |
| main.rs:2232:41:2232:41 | 3 | | {EXTERNAL LOCATION} | u32 |
-| main.rs:2233:13:2233:13 | u | | {EXTERNAL LOCATION} | Vec |
| main.rs:2233:13:2233:13 | u | | {EXTERNAL LOCATION} | i32 |
| main.rs:2233:13:2233:13 | u | | {EXTERNAL LOCATION} | u32 |
| main.rs:2233:13:2233:13 | u | | file://:0:0:0:0 | & |
-| main.rs:2233:13:2233:13 | u | A | {EXTERNAL LOCATION} | Global |
-| main.rs:2233:13:2233:13 | u | T | {EXTERNAL LOCATION} | i32 |
-| main.rs:2233:13:2233:13 | u | T | {EXTERNAL LOCATION} | u32 |
| main.rs:2233:18:2233:22 | vals5 | | {EXTERNAL LOCATION} | Vec |
| main.rs:2233:18:2233:22 | vals5 | A | {EXTERNAL LOCATION} | Global |
| main.rs:2233:18:2233:22 | vals5 | T | {EXTERNAL LOCATION} | i32 |
@@ -3801,12 +3798,8 @@ inferType
| main.rs:2235:39:2235:39 | 2 | | {EXTERNAL LOCATION} | u64 |
| main.rs:2235:42:2235:42 | 3 | | {EXTERNAL LOCATION} | i32 |
| main.rs:2235:42:2235:42 | 3 | | {EXTERNAL LOCATION} | u64 |
-| main.rs:2236:13:2236:13 | u | | {EXTERNAL LOCATION} | Vec |
| main.rs:2236:13:2236:13 | u | | file://:0:0:0:0 | & |
| main.rs:2236:13:2236:13 | u | &T | {EXTERNAL LOCATION} | u64 |
-| main.rs:2236:13:2236:13 | u | A | {EXTERNAL LOCATION} | Global |
-| main.rs:2236:13:2236:13 | u | T | file://:0:0:0:0 | & |
-| main.rs:2236:13:2236:13 | u | T.&T | {EXTERNAL LOCATION} | u64 |
| main.rs:2236:18:2236:22 | vals6 | | {EXTERNAL LOCATION} | Vec |
| main.rs:2236:18:2236:22 | vals6 | A | {EXTERNAL LOCATION} | Global |
| main.rs:2236:18:2236:22 | vals6 | T | file://:0:0:0:0 | & |
@@ -3821,11 +3814,8 @@ inferType
| main.rs:2239:9:2239:13 | vals7 | A | {EXTERNAL LOCATION} | Global |
| main.rs:2239:9:2239:13 | vals7 | T | {EXTERNAL LOCATION} | u8 |
| main.rs:2239:20:2239:22 | 1u8 | | {EXTERNAL LOCATION} | u8 |
-| main.rs:2240:13:2240:13 | u | | {EXTERNAL LOCATION} | Vec |
| main.rs:2240:13:2240:13 | u | | {EXTERNAL LOCATION} | u8 |
| main.rs:2240:13:2240:13 | u | | file://:0:0:0:0 | & |
-| main.rs:2240:13:2240:13 | u | A | {EXTERNAL LOCATION} | Global |
-| main.rs:2240:13:2240:13 | u | T | {EXTERNAL LOCATION} | u8 |
| main.rs:2240:18:2240:22 | vals7 | | {EXTERNAL LOCATION} | Vec |
| main.rs:2240:18:2240:22 | vals7 | A | {EXTERNAL LOCATION} | Global |
| main.rs:2240:18:2240:22 | vals7 | T | {EXTERNAL LOCATION} | u8 |
From 8ebebf03c20623a8d9948a4ed8c5af53fa1329ce Mon Sep 17 00:00:00 2001
From: Simon Friis Vindum
Date: Mon, 21 Jul 2025 10:11:41 +0200
Subject: [PATCH 3/4] Rust: Add type inference test with associated type that
collides with type parameter
---
.../test/library-tests/type-inference/main.rs | 33 +-
.../type-inference/type-inference.expected | 5171 +++++++++--------
2 files changed, 2626 insertions(+), 2578 deletions(-)
diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs
index b6a8fdca36ca..bff92978927b 100644
--- a/rust/ql/test/library-tests/type-inference/main.rs
+++ b/rust/ql/test/library-tests/type-inference/main.rs
@@ -1042,6 +1042,23 @@ mod type_aliases {
type S7 = Result, S1>;
+ struct GenS(GenT);
+
+ trait TraitWithAssocType {
+ type Output;
+ fn get_input(self) -> Self::Output;
+ }
+
+ impl