mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Rust: Handle unqualified UseTrees in path resolution
This commit is contained in:
@@ -1457,6 +1457,24 @@ private predicate crateDependencyEdge(SourceFileItemNode file, string name, Crat
|
||||
not hasDeclOrDep(file, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `UseTree` that is nested under `tree`, and which needs to be resolved
|
||||
* relative to the path of `tree`.
|
||||
*
|
||||
* `tree` is restricted to either having a path or being a direct child of some
|
||||
* `use` statement without a path.
|
||||
*/
|
||||
private UseTree getAUseTreeUseTree(UseTree tree) {
|
||||
result = tree.getUseTreeList().getAUseTree() and
|
||||
(if tree.hasPath() then any() else tree = any(Use u).getUseTree())
|
||||
or
|
||||
exists(UseTree mid |
|
||||
mid = getAUseTreeUseTree(tree) and
|
||||
not mid.hasPath() and
|
||||
result = mid.getUseTreeList().getAUseTree()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate useTreeDeclares(UseTree tree, string name) {
|
||||
not tree.isGlob() and
|
||||
not exists(tree.getUseTreeList()) and
|
||||
@@ -1470,7 +1488,7 @@ private predicate useTreeDeclares(UseTree tree, string name) {
|
||||
or
|
||||
exists(UseTree mid |
|
||||
useTreeDeclares(mid, name) and
|
||||
mid = tree.getUseTreeList().getAUseTree()
|
||||
mid = getAUseTreeUseTree(tree)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1511,7 +1529,10 @@ class RelevantPath extends Path {
|
||||
pragma[nomagic]
|
||||
predicate isUnqualified(string name) {
|
||||
not exists(this.getQualifier()) and
|
||||
not this = any(UseTreeList list).getAUseTree().getPath().getQualifier*() and
|
||||
not exists(UseTree tree |
|
||||
tree.hasPath() and
|
||||
this = getAUseTreeUseTree(tree).getPath().getQualifier*()
|
||||
) and
|
||||
name = this.getText()
|
||||
}
|
||||
|
||||
@@ -1990,7 +2011,7 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
|
||||
exists(UseOption useOpt | checkQualifiedVisibility(use, result, kind, useOpt) |
|
||||
exists(UseTree midTree, ItemNode mid, string name |
|
||||
mid = resolveUseTreeListItem(use, midTree) and
|
||||
tree = midTree.getUseTreeList().getAUseTree() and
|
||||
tree = getAUseTreeUseTree(midTree) and
|
||||
isUseTreeSubPathUnqualified(tree, path, pragma[only_bind_into](name)) and
|
||||
result = mid.getASuccessor(pragma[only_bind_into](name), kind, useOpt)
|
||||
)
|
||||
@@ -2010,14 +2031,31 @@ private ItemNode resolveUseTreeListItemQualifier(
|
||||
name = path.getText()
|
||||
}
|
||||
|
||||
private UseTree getAUseUseTree(Use use) {
|
||||
exists(UseTree root | root = use.getUseTree() |
|
||||
result = root
|
||||
or
|
||||
not root.hasPath() and
|
||||
result = getAUseTreeUseTree(root)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ItemNode resolveUseTreeListItem(Use use, UseTree tree) {
|
||||
exists(Path path | path = tree.getPath() |
|
||||
tree = use.getUseTree() and
|
||||
tree = getAUseUseTree(use) and
|
||||
result = resolvePathCand(path)
|
||||
or
|
||||
result = resolveUseTreeListItem(use, tree, path, _)
|
||||
)
|
||||
or
|
||||
exists(UseTree midTree |
|
||||
// `use foo::{bar, *}`; midTree = `foo` and tree = `*`
|
||||
result = resolveUseTreeListItem(use, midTree) and
|
||||
tree = getAUseTreeUseTree(midTree) and
|
||||
tree.isGlob() and
|
||||
not tree.hasPath()
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `use` imports `item` as `name`. */
|
||||
@@ -2159,6 +2197,16 @@ private module Debug {
|
||||
result = resolvePath(path)
|
||||
}
|
||||
|
||||
ItemNode debugResolveUseTreeListItem(Use use, UseTree tree, RelevantPath path, SuccessorKind kind) {
|
||||
use = getRelevantLocatable() and
|
||||
result = resolveUseTreeListItem(use, tree, path, kind)
|
||||
}
|
||||
|
||||
ItemNode debugResolveUseTreeListItem(Use use, UseTree tree) {
|
||||
use = getRelevantLocatable() and
|
||||
result = resolveUseTreeListItem(use, tree)
|
||||
}
|
||||
|
||||
predicate debugUseImportEdge(Use use, string name, ItemNode item, SuccessorKind kind) {
|
||||
use = getRelevantLocatable() and
|
||||
useImportEdge(use, name, item, kind)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
mod my; // I1
|
||||
|
||||
#[rustfmt::skip]
|
||||
use {{{my::{{self as my_alias, *}}}}}; // $ MISSING: item=I1
|
||||
use {{{my::{{self as my_alias, *}}}}}; // $ item=I1
|
||||
|
||||
use my::nested::nested1::nested2::*; // $ item=I3
|
||||
|
||||
@@ -816,8 +816,8 @@ fn main() {
|
||||
nested6::f(); // $ item=I116
|
||||
nested8::f(); // $ item=I119
|
||||
my3::f(); // $ item=I200
|
||||
nested_f(); // $ MISSING: item=I201
|
||||
my_alias::nested_f(); // $ MISSING: item=I201
|
||||
nested_f(); // $ item=I201
|
||||
my_alias::nested_f(); // $ item=I201
|
||||
m18::m19::m20::g(); // $ item=I103
|
||||
m23::f(); // $ item=I108
|
||||
m24::f(); // $ item=I121
|
||||
|
||||
@@ -47,6 +47,8 @@ mod
|
||||
| my/nested.rs:1:1:17:1 | mod nested1 |
|
||||
| my/nested.rs:2:5:11:5 | mod nested2 |
|
||||
resolvePath
|
||||
| main.rs:4:8:4:9 | my | main.rs:1:1:1:7 | mod my |
|
||||
| main.rs:4:14:4:17 | self | main.rs:1:1:1:7 | mod my |
|
||||
| main.rs:6:5:6:6 | my | main.rs:1:1:1:7 | mod my |
|
||||
| main.rs:6:5:6:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
|
||||
| main.rs:6:5:6:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |
|
||||
@@ -447,6 +449,9 @@ resolvePath
|
||||
| main.rs:817:5:817:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f |
|
||||
| main.rs:818:5:818:7 | my3 | my2/mod.rs:20:1:20:12 | mod my3 |
|
||||
| main.rs:818:5:818:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f |
|
||||
| main.rs:819:5:819:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
|
||||
| main.rs:820:5:820:12 | my_alias | main.rs:1:1:1:7 | mod my |
|
||||
| main.rs:820:5:820:22 | ...::nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
|
||||
| main.rs:821:5:821:7 | m18 | main.rs:555:1:573:1 | mod m18 |
|
||||
| main.rs:821:5:821:12 | ...::m19 | main.rs:560:5:572:5 | mod m19 |
|
||||
| main.rs:821:5:821:17 | ...::m20 | main.rs:565:9:571:9 | mod m20 |
|
||||
|
||||
Reference in New Issue
Block a user