Skip to content

Commit e72aba7

Browse files
committedApr 23, 2025
Rust: Path resolution performance tweaks
1 parent c11ed6d commit e72aba7

File tree

1 file changed

+48
-25
lines changed

1 file changed

+48
-25
lines changed
 

‎rust/ql/lib/codeql/rust/internal/PathResolution.qll

+48-25
Original file line numberDiff line numberDiff line change
@@ -856,41 +856,54 @@ class RelevantPath extends Path {
856856
}
857857
}
858858

859+
private predicate isModule(ItemNode m) { m instanceof Module }
860+
861+
/** Holds if root module `root` contains the module `m`. */
862+
private predicate rootHasModule(ItemNode root, ItemNode m) =
863+
doublyBoundedFastTC(hasChild/2, isRoot/1, isModule/1)(root, m)
864+
865+
pragma[nomagic]
866+
private ItemNode getOuterScope(ItemNode i) {
867+
// nested modules do not have unqualified access to items from outer modules,
868+
// except for items declared at top-level in the root module
869+
rootHasModule(result, i)
870+
or
871+
not i instanceof Module and
872+
result = i.getImmediateParent()
873+
}
874+
875+
pragma[nomagic]
876+
private ItemNode getAdjustedEnclosing(ItemNode encl0, Namespace ns) {
877+
// functions in `impl` blocks need to use explicit `Self::` to access other
878+
// functions in the `impl` block
879+
if encl0 instanceof ImplOrTraitItemNode and ns.isValue()
880+
then result = encl0.getImmediateParent()
881+
else result = encl0
882+
}
883+
859884
/**
860885
* Holds if the unqualified path `p` references an item named `name`, and `name`
861886
* may be looked up in the `ns` namespace inside enclosing item `encl`.
862887
*/
863888
pragma[nomagic]
864-
private predicate unqualifiedPathLookup(RelevantPath p, string name, Namespace ns, ItemNode encl) {
865-
exists(ItemNode encl0 |
889+
private predicate unqualifiedPathLookup(ItemNode encl, string name, Namespace ns, RelevantPath p) {
890+
exists(ItemNode encl0 | encl = getAdjustedEnclosing(encl0, ns) |
866891
// lookup in the immediately enclosing item
867892
p.isUnqualified(name) and
868893
encl0.getADescendant() = p and
869894
exists(ns) and
870-
not name = ["crate", "$crate"]
895+
not name = ["crate", "$crate", "super", "self"]
871896
or
872897
// lookup in an outer scope, but only if the item is not declared in inner scope
873898
exists(ItemNode mid |
874-
unqualifiedPathLookup(p, name, ns, mid) and
899+
unqualifiedPathLookup(mid, name, ns, p) and
875900
not declares(mid, ns, name) and
876-
not name = ["super", "self"] and
877901
not (
878902
name = "Self" and
879903
mid = any(ImplOrTraitItemNode i).getAnItemInSelfScope()
880-
)
881-
|
882-
// nested modules do not have unqualified access to items from outer modules,
883-
// except for items declared at top-level in the root module
884-
if mid instanceof Module
885-
then encl0 = mid.getImmediateParent+() and encl0.(ModuleLikeNode).isRoot()
886-
else encl0 = mid.getImmediateParent()
904+
) and
905+
encl0 = getOuterScope(mid)
887906
)
888-
|
889-
// functions in `impl` blocks need to use explicit `Self::` to access other
890-
// functions in the `impl` block
891-
if encl0 instanceof ImplOrTraitItemNode and ns.isValue()
892-
then encl = encl0.getImmediateParent()
893-
else encl = encl0
894907
)
895908
}
896909

@@ -909,24 +922,34 @@ private predicate hasChild(ItemNode parent, ItemNode child) { child.getImmediate
909922
private predicate rootHasCratePathTc(ItemNode i1, ItemNode i2) =
910923
doublyBoundedFastTC(hasChild/2, isRoot/1, hasCratePath/1)(i1, i2)
911924

925+
/**
926+
* Holds if the unqualified path `p` references a keyword item named `name`, and
927+
* `name` may be looked up in the `ns` namespace inside enclosing item `encl`.
928+
*/
912929
pragma[nomagic]
913-
private predicate unqualifiedPathLookup1(RelevantPath p, string name, Namespace ns, ItemNode encl) {
914-
unqualifiedPathLookup(p, name, ns, encl)
915-
or
930+
private predicate keywordLookup(ItemNode encl, string name, Namespace ns, RelevantPath p) {
916931
// For `($)crate`, jump directly to the root module
917932
exists(ItemNode i | p.isCratePath(name, i) |
918933
encl.(ModuleLikeNode).isRoot() and
919934
encl = i
920935
or
921936
rootHasCratePathTc(encl, i)
922937
)
938+
or
939+
name = ["super", "self"] and
940+
p.isUnqualified(name) and
941+
exists(ItemNode encl0 |
942+
encl0.getADescendant() = p and
943+
encl = getAdjustedEnclosing(encl0, ns)
944+
)
923945
}
924946

925947
pragma[nomagic]
926-
private ItemNode unqualifiedPathLookup(RelevantPath path, Namespace ns) {
927-
exists(ItemNode encl, string name |
928-
result = getASuccessor(encl, name, ns) and
929-
unqualifiedPathLookup1(path, name, ns, encl)
948+
private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns) {
949+
exists(ItemNode encl, string name | result = getASuccessor(encl, name, ns) |
950+
unqualifiedPathLookup(encl, name, ns, p)
951+
or
952+
keywordLookup(encl, name, ns, p)
930953
)
931954
}
932955

0 commit comments

Comments
 (0)