mirror of
https://github.com/github/codeql.git
synced 2026-04-23 07:45:17 +02:00
Rust: More path resolution improvements
This commit is contained in:
@@ -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]
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
|
||||
|
||||
Reference in New Issue
Block a user