From f6ac82aff04c09471f36281abe46225c121ab156 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 27 Mar 2025 15:10:14 +0100 Subject: [PATCH 1/2] Rust: Add more path resolution tests --- .../library-tests/path-resolution/main.rs | 22 ++++ .../test/library-tests/path-resolution/my.rs | 6 + .../path-resolution/my/my4/my5/mod.rs | 3 + .../path-resolution/path-resolution.expected | 124 ++++++++++-------- 4 files changed, 101 insertions(+), 54 deletions(-) create mode 100644 rust/ql/test/library-tests/path-resolution/my/my4/my5/mod.rs diff --git a/rust/ql/test/library-tests/path-resolution/main.rs b/rust/ql/test/library-tests/path-resolution/main.rs index 7857ddc6cf5f..6b2052a1b3c9 100644 --- a/rust/ql/test/library-tests/path-resolution/main.rs +++ b/rust/ql/test/library-tests/path-resolution/main.rs @@ -473,6 +473,26 @@ mod m17 { } // I99 } +mod m18 { + fn f() { + println!("m18::f"); + } // I101 + + pub mod m19 { + fn f() { + println!("m18::m19::f"); + } // I102 + + pub mod m20 { + pub fn g() { + println!("m18::m19::m20::g"); + super::f(); // $ item=I102 + super::super::f(); // $ item=I101 + } // I103 + } + } +} + fn main() { my::nested::nested1::nested2::f(); // $ item=I4 my::f(); // $ item=I38 @@ -498,4 +518,6 @@ fn main() { nested6::f(); // $ item=I116 nested8::f(); // $ item=I119 my3::f(); // $ item=I200 + nested_f(); // $ MISSING: item=I201 + m18::m19::m20::g(); // $ item=I103 } diff --git a/rust/ql/test/library-tests/path-resolution/my.rs b/rust/ql/test/library-tests/path-resolution/my.rs index fd9511a21181..487b0e78769c 100644 --- a/rust/ql/test/library-tests/path-resolution/my.rs +++ b/rust/ql/test/library-tests/path-resolution/my.rs @@ -10,3 +10,9 @@ pub fn h() { println!("my.rs::h"); g(); // $ item=I7 } // I39 + +mod my4 { + pub mod my5; +} + +pub use my4::my5::f as nested_f; // $ MISSING: item=I201 diff --git a/rust/ql/test/library-tests/path-resolution/my/my4/my5/mod.rs b/rust/ql/test/library-tests/path-resolution/my/my4/my5/mod.rs new file mode 100644 index 000000000000..25a94fee7c14 --- /dev/null +++ b/rust/ql/test/library-tests/path-resolution/my/my4/my5/mod.rs @@ -0,0 +1,3 @@ +pub fn f() { + println!("my/my4/my5/mod.rs::f"); +} // I201 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 51dcc55b9e2d..6bf3f6567346 100644 --- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected +++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected @@ -21,6 +21,9 @@ mod | main.rs:294:1:348:1 | mod m15 | | main.rs:350:1:442:1 | mod m16 | | main.rs:444:1:474:1 | mod m17 | +| main.rs:476:1:494:1 | mod m18 | +| main.rs:481:5:493:5 | mod m19 | +| main.rs:486:9:492:9 | mod m20 | | my2/mod.rs:1:1:1:16 | mod nested2 | | my2/mod.rs:12:1:12:12 | mod my3 | | my2/nested2.rs:1:1:11:1 | mod nested3 | @@ -30,6 +33,8 @@ mod | my2/nested2.rs:21:1:27:1 | mod nested7 | | my2/nested2.rs:22:5:26:5 | mod nested8 | | my.rs:1:1:1:15 | mod nested | +| my.rs:14:1:16:1 | mod my4 | +| my.rs:15:5:15:16 | mod my5 | | my/nested.rs:1:1:17:1 | mod nested1 | | my/nested.rs:2:5:11:5 | mod nested2 | resolvePath @@ -51,7 +56,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:501:2 | SourceFile | +| main.rs:40:9:40:13 | super | main.rs:1:1:523: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 | @@ -63,7 +68,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:501:2 | SourceFile | +| main.rs:68:5:68:8 | self | main.rs:1:1:523: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:81:17:81:19 | Foo | main.rs:77:9:79:9 | struct Foo | @@ -77,7 +82,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:501:2 | SourceFile | +| main.rs:117:13:117:17 | super | main.rs:1:1:523: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 | @@ -210,56 +215,65 @@ resolvePath | main.rs:465:9:465:18 | ...::f | main.rs:446:9:446:20 | fn f | | main.rs:470:9:470:9 | g | main.rs:459:5:466:5 | fn g | | main.rs:471:11:471:11 | S | main.rs:449:5:449:13 | struct S | -| main.rs:477:5:477:6 | my | main.rs:1:1:1:7 | mod my | -| main.rs:477:5:477:14 | ...::nested | my.rs:1:1:1:15 | mod nested | -| main.rs:477:5:477:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 | -| main.rs:477:5:477:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 | -| main.rs:477:5:477:35 | ...::f | my/nested.rs:3:9:5:9 | fn f | -| main.rs:478:5:478:6 | my | main.rs:1:1:1:7 | mod my | -| main.rs:478:5:478:9 | ...::f | my.rs:5:1:7:1 | fn f | -| main.rs:479:5:479:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | -| main.rs:479:5:479:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | -| main.rs:479:5:479:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | -| main.rs:479:5:479:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:480:5:480:5 | f | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:481:5:481:5 | g | my2/nested2.rs:7:9:9:9 | fn g | -| main.rs:482:5:482:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) | -| main.rs:482:5:482:12 | ...::h | main.rs:50:1:69:1 | fn h | -| main.rs:483:5:483:6 | m1 | main.rs:13:1:37:1 | mod m1 | -| main.rs:483:5:483:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 | -| main.rs:483:5:483:13 | ...::g | main.rs:23:9:27:9 | fn g | -| main.rs:484:5:484:6 | m1 | main.rs:13:1:37:1 | mod m1 | -| main.rs:484:5:484:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 | -| main.rs:484:5:484:14 | ...::m3 | main.rs:29:9:35:9 | mod m3 | -| main.rs:484:5:484:17 | ...::h | main.rs:30:27:34:13 | fn h | -| main.rs:485:5:485:6 | m4 | main.rs:39:1:46:1 | mod m4 | -| main.rs:485:5:485:9 | ...::i | main.rs:42:5:45:5 | fn i | -| main.rs:486:5:486:5 | h | main.rs:50:1:69:1 | fn h | -| main.rs:487:5:487:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:488:5:488:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g | -| main.rs:489:5:489:5 | j | main.rs:97:1:101:1 | fn j | -| main.rs:490:5:490:6 | m6 | main.rs:109:1:120:1 | mod m6 | -| main.rs:490:5:490:9 | ...::g | main.rs:114:5:119:5 | fn g | -| main.rs:491:5:491:6 | m7 | main.rs:122:1:137:1 | mod m7 | -| main.rs:491:5:491:9 | ...::f | main.rs:129:5:136:5 | fn f | -| main.rs:492:5:492:6 | m8 | main.rs:139:1:193:1 | mod m8 | -| main.rs:492:5:492:9 | ...::g | main.rs:177:5:192:5 | fn g | -| main.rs:493:5:493:6 | m9 | main.rs:195:1:203:1 | mod m9 | -| main.rs:493:5:493:9 | ...::f | main.rs:198:5:202:5 | fn f | -| main.rs:494:5:494:7 | m11 | main.rs:226:1:263:1 | mod m11 | -| main.rs:494:5:494:10 | ...::f | main.rs:231:5:234:5 | fn f | -| main.rs:495:5:495:7 | m15 | main.rs:294:1:348:1 | mod m15 | -| main.rs:495:5:495:10 | ...::f | main.rs:335:5:347:5 | fn f | -| main.rs:496:5:496:7 | m16 | main.rs:350:1:442:1 | mod m16 | -| main.rs:496:5:496:10 | ...::f | main.rs:417:5:441:5 | fn f | -| main.rs:497:5:497:7 | m17 | main.rs:444:1:474:1 | mod m17 | -| main.rs:497:5:497:10 | ...::f | main.rs:468:5:473:5 | fn f | -| main.rs:498:5:498:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 | -| main.rs:498:5:498:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f | -| main.rs:499:5:499:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 | -| main.rs:499:5:499:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f | -| main.rs:500:5:500:7 | my3 | my2/mod.rs:12:1:12:12 | mod my3 | -| main.rs:500:5:500:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f | +| main.rs:489:17:489:21 | super | main.rs:481:5:493:5 | mod m19 | +| main.rs:489:17:489:24 | ...::f | main.rs:482:9:484:9 | fn f | +| main.rs:490:17:490:21 | super | main.rs:481:5:493:5 | mod m19 | +| main.rs:490:17:490:28 | ...::super | main.rs:476:1:494:1 | mod m18 | +| main.rs:490:17:490:31 | ...::f | main.rs:477:5:479:5 | fn f | +| main.rs:497:5:497:6 | my | main.rs:1:1:1:7 | mod my | +| main.rs:497:5:497:14 | ...::nested | my.rs:1:1:1:15 | mod nested | +| main.rs:497:5:497:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 | +| main.rs:497:5:497:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 | +| main.rs:497:5:497:35 | ...::f | my/nested.rs:3:9:5:9 | fn f | +| main.rs:498:5:498:6 | my | main.rs:1:1:1:7 | mod my | +| main.rs:498:5:498:9 | ...::f | my.rs:5:1:7:1 | fn f | +| main.rs:499:5:499:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | +| main.rs:499:5:499:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | +| main.rs:499:5:499:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | +| main.rs:499:5:499:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:500:5:500:5 | f | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:501:5:501:5 | g | my2/nested2.rs:7:9:9:9 | fn g | +| main.rs:502:5:502:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) | +| main.rs:502:5:502:12 | ...::h | main.rs:50:1:69:1 | fn h | +| main.rs:503:5:503:6 | m1 | main.rs:13:1:37:1 | mod m1 | +| main.rs:503:5:503:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 | +| main.rs:503:5:503:13 | ...::g | main.rs:23:9:27:9 | fn g | +| main.rs:504:5:504:6 | m1 | main.rs:13:1:37:1 | mod m1 | +| main.rs:504:5:504:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 | +| main.rs:504:5:504:14 | ...::m3 | main.rs:29:9:35:9 | mod m3 | +| main.rs:504:5:504:17 | ...::h | main.rs:30:27:34:13 | fn h | +| main.rs:505:5:505:6 | m4 | main.rs:39:1:46:1 | mod m4 | +| main.rs:505:5:505:9 | ...::i | main.rs:42:5:45:5 | fn i | +| main.rs:506:5:506:5 | h | main.rs:50:1:69:1 | fn h | +| main.rs:507:5:507:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:508:5:508:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g | +| main.rs:509:5:509:5 | j | main.rs:97:1:101:1 | fn j | +| main.rs:510:5:510:6 | m6 | main.rs:109:1:120:1 | mod m6 | +| main.rs:510:5:510:9 | ...::g | main.rs:114:5:119:5 | fn g | +| main.rs:511:5:511:6 | m7 | main.rs:122:1:137:1 | mod m7 | +| main.rs:511:5:511:9 | ...::f | main.rs:129:5:136:5 | fn f | +| main.rs:512:5:512:6 | m8 | main.rs:139:1:193:1 | mod m8 | +| main.rs:512:5:512:9 | ...::g | main.rs:177:5:192:5 | fn g | +| main.rs:513:5:513:6 | m9 | main.rs:195:1:203:1 | mod m9 | +| main.rs:513:5:513:9 | ...::f | main.rs:198:5:202:5 | fn f | +| main.rs:514:5:514:7 | m11 | main.rs:226:1:263:1 | mod m11 | +| main.rs:514:5:514:10 | ...::f | main.rs:231:5:234:5 | fn f | +| main.rs:515:5:515:7 | m15 | main.rs:294:1:348:1 | mod m15 | +| main.rs:515:5:515:10 | ...::f | main.rs:335:5:347:5 | fn f | +| main.rs:516:5:516:7 | m16 | main.rs:350:1:442:1 | mod m16 | +| main.rs:516:5:516:10 | ...::f | main.rs:417:5:441:5 | fn f | +| main.rs:517:5:517:7 | m17 | main.rs:444:1:474:1 | mod m17 | +| main.rs:517:5:517:10 | ...::f | main.rs:468:5:473:5 | fn f | +| main.rs:518:5:518:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 | +| main.rs:518:5:518:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f | +| main.rs:519:5:519:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 | +| main.rs:519:5:519:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f | +| main.rs:520:5:520:7 | my3 | my2/mod.rs:12:1:12:12 | mod my3 | +| main.rs:520:5:520:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f | +| main.rs:522:5:522:7 | m18 | main.rs:476:1:494:1 | mod m18 | +| main.rs:522:5:522:12 | ...::m19 | main.rs:481:5:493:5 | mod m19 | +| main.rs:522:5:522:17 | ...::m20 | main.rs:486:9:492:9 | mod m20 | +| main.rs:522:5:522:20 | ...::g | main.rs:487:13:491:13 | fn g | | 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 | @@ -273,13 +287,15 @@ 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:12:13 | SourceFile | -| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:501:2 | SourceFile | +| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:523: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:12:13 | SourceFile | | my2/my3/mod.rs:8:5:8:12 | ...::g | my2/mod.rs:3:1:6:1 | fn g | | my.rs:3:5:3:10 | nested | my.rs:1:1:1:15 | mod nested | | my.rs:3:5:3:13 | ...::g | my/nested.rs:19:1:22:1 | fn g | | my.rs:11:5:11:5 | g | my/nested.rs:19:1:22:1 | fn g | +| my.rs:18:9:18:11 | my4 | my.rs:14:1:16:1 | mod my4 | +| my.rs:18:9:18:16 | ...::my5 | my.rs:15:5:15:16 | mod my5 | | my/nested.rs:9:13:9:13 | f | my/nested.rs:3:9:5:9 | fn f | | my/nested.rs:15:9:15:15 | nested2 | my/nested.rs:2:5:11:5 | mod nested2 | | my/nested.rs:15:9:15:18 | ...::f | my/nested.rs:3:9:5:9 | fn f | From 605cf359706695f0dbba46c411a393861297d9bf Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 27 Mar 2025 15:10:25 +0100 Subject: [PATCH 2/2] Rust: More path resolution improvements --- .../codeql/rust/internal/PathResolution.qll | 101 ++++++++++++++---- .../library-tests/path-resolution/main.rs | 2 +- .../test/library-tests/path-resolution/my.rs | 2 +- .../path-resolution/path-resolution.expected | 2 + 4 files changed, 84 insertions(+), 23 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 2128bb8e7a82..ae4ed9cf7265 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -116,7 +116,7 @@ abstract class ItemNode extends Locatable { } pragma[nomagic] - private ItemNode getASuccessorRec(string name) { + ItemNode getASuccessorRec(string name) { sourceFileEdge(this, name, result) or this = result.getImmediateParent() and @@ -613,11 +613,11 @@ private predicate fileModule(SourceFile f, string name, Folder folder) { } /** - * Holds if `m` is a `mod name;` module declaration happening in a file named - * `fileName.rs`, inside the folder `parent`. + * Holds if `m` is a `mod name;` module declaration, where the corresponding + * module file needs to be looked up in `lookup` or one of its descandants. */ -private predicate modImport(Module m, string fileName, string name, Folder parent) { - exists(File f | +private predicate modImport0(Module m, string name, Folder lookup) { + exists(File f, Folder parent, string fileName | f = m.getFile() and not m.hasItemList() and // TODO: handle @@ -629,17 +629,63 @@ private predicate modImport(Module m, string fileName, string name, Folder paren name = m.getName().getText() and parent = f.getParentContainer() and fileName = f.getStem() + | + // sibling import + lookup = parent and + ( + m.getFile() = any(CrateItemNode c).getModuleNode().(SourceFileItemNode).getFile() + or + m.getFile().getBaseName() = "mod.rs" + ) + or + // child import + lookup = parent.getFolder(fileName) + ) +} + +/** + * Holds if `m` is a `mod name;` module declaration, which happens inside a + * nested module, and `pred -> succ` is a module edge leading to `m`. + */ +private predicate modImportNested(ModuleItemNode m, ModuleItemNode pred, ModuleItemNode succ) { + pred.getAnItemInScope() = succ and + ( + modImport0(m, _, _) and + succ = m + or + modImportNested(m, succ, _) + ) +} + +/** + * Holds if `m` is a `mod name;` module declaration, which happens inside a + * nested module, where `ancestor` is a reflexive transitive ancestor module + * of `m` with corresponding lookup folder `lookup`. + */ +private predicate modImportNestedLookup(Module m, ModuleItemNode ancestor, Folder lookup) { + modImport0(m, _, lookup) and + modImportNested(m, ancestor, _) and + not modImportNested(m, _, ancestor) + or + exists(ModuleItemNode m1, Folder mid | + modImportNestedLookup(m, m1, mid) and + modImportNested(m, m1, ancestor) and + lookup = mid.getFolder(m1.getName()) ) } /** Holds if `m` is a `mod name;` item importing file `f`. */ private predicate fileImport(Module m, SourceFile f) { - exists(string fileName, string name, Folder parent | modImport(m, fileName, name, parent) | - // sibling import + exists(string name, Folder parent | + modImport0(m, name, _) and fileModule(f, name, parent) + | + // `m` is not inside a nested module + modImport0(m, name, parent) and + not modImportNested(m, _, _) or - // child import - fileModule(f, name, parent.getFolder(fileName)) + // `m` is inside a nested module + modImportNestedLookup(m, m, parent) ) } @@ -651,7 +697,7 @@ pragma[nomagic] private predicate fileImportEdge(Module mod, string name, ItemNode item) { exists(SourceFileItemNode f | fileImport(mod, f) and - item = f.getASuccessor(name) + item = f.getASuccessorRec(name) ) } @@ -660,7 +706,7 @@ private predicate fileImportEdge(Module mod, string name, ItemNode item) { */ pragma[nomagic] private predicate crateDefEdge(CrateItemNode c, string name, ItemNode i) { - i = c.getModuleNode().getASuccessor(name) and + i = c.getModuleNode().getASuccessorRec(name) and not i instanceof Crate } @@ -742,7 +788,16 @@ private predicate unqualifiedPathLookup(RelevantPath p, string name, Namespace n // lookup in an outer scope, but only if the item is not declared in inner scope exists(ItemNode mid | unqualifiedPathLookup(p, name, ns, mid) and - not declares(mid, ns, name) + not declares(mid, ns, name) and + not name = ["super", "self"] and + not ( + name = "Self" and + mid = any(ImplOrTraitItemNode i).getAnItemInSelfScope() + ) and + not ( + name = "crate" and + mid = any(CrateItemNode i).getASourceFile() + ) | // nested modules do not have unqualified access to items from outer modules, // except for items declared at top-level in the source file @@ -943,15 +998,19 @@ private predicate useImportEdge(Use use, string name, ItemNode item) { encl.getADescendant() = use and item = getASuccessor(used, name, ns) and // glob imports can be shadowed - not declares(encl, ns, name) + not declares(encl, ns, name) and + not name = ["super", "self", "Self", "crate"] ) - else item = used - | - not tree.hasRename() and - name = item.getName() - or - name = tree.getRename().getName().getText() and - name != "_" + else ( + item = used and + ( + not tree.hasRename() and + name = item.getName() + or + name = tree.getRename().getName().getText() and + name != "_" + ) + ) ) } @@ -961,7 +1020,7 @@ private module Debug { exists(string filepath, int startline, int startcolumn, int endline, int endcolumn | result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and filepath.matches("%/main.rs") and - startline = 1 + startline = [1, 3] ) } diff --git a/rust/ql/test/library-tests/path-resolution/main.rs b/rust/ql/test/library-tests/path-resolution/main.rs index 6b2052a1b3c9..374f290b00e1 100644 --- a/rust/ql/test/library-tests/path-resolution/main.rs +++ b/rust/ql/test/library-tests/path-resolution/main.rs @@ -518,6 +518,6 @@ fn main() { nested6::f(); // $ item=I116 nested8::f(); // $ item=I119 my3::f(); // $ item=I200 - nested_f(); // $ MISSING: item=I201 + nested_f(); // $ item=I201 m18::m19::m20::g(); // $ item=I103 } diff --git a/rust/ql/test/library-tests/path-resolution/my.rs b/rust/ql/test/library-tests/path-resolution/my.rs index 487b0e78769c..2dcb1c76aebc 100644 --- a/rust/ql/test/library-tests/path-resolution/my.rs +++ b/rust/ql/test/library-tests/path-resolution/my.rs @@ -15,4 +15,4 @@ mod my4 { pub mod my5; } -pub use my4::my5::f as nested_f; // $ MISSING: item=I201 +pub use my4::my5::f as nested_f; // $ item=I201 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 6bf3f6567346..235ad7451c56 100644 --- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected +++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected @@ -270,6 +270,7 @@ resolvePath | main.rs:519:5:519:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f | | main.rs:520:5:520:7 | my3 | my2/mod.rs:12:1:12:12 | mod my3 | | main.rs:520:5:520:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f | +| main.rs:521:5:521:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f | | main.rs:522:5:522:7 | m18 | main.rs:476:1:494:1 | mod m18 | | main.rs:522:5:522:12 | ...::m19 | main.rs:481:5:493:5 | mod m19 | | main.rs:522:5:522:17 | ...::m20 | main.rs:486:9:492:9 | mod m20 | @@ -296,6 +297,7 @@ resolvePath | my.rs:11:5:11:5 | g | my/nested.rs:19:1:22:1 | fn g | | my.rs:18:9:18:11 | my4 | my.rs:14:1:16:1 | mod my4 | | my.rs:18:9:18:16 | ...::my5 | my.rs:15:5:15:16 | mod my5 | +| my.rs:18:9:18:19 | ...::f | my/my4/my5/mod.rs:1:1:3:1 | fn f | | my/nested.rs:9:13:9:13 | f | my/nested.rs:3:9:5:9 | fn f | | my/nested.rs:15:9:15:15 | nested2 | my/nested.rs:2:5:11:5 | mod nested2 | | my/nested.rs:15:9:15:18 | ...::f | my/nested.rs:3:9:5:9 | fn f |