Skip to content

Commit 432435f

Browse files
authored
Merge pull request #19358 from hvitved/rust/path-resolution-perf-tweaks
Rust: Path resolution performance tweaks
2 parents 8b95e0e + e72aba7 commit 432435f

File tree

1 file changed

+48
-25
lines changed

1 file changed

+48
-25
lines changed

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

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -864,41 +864,54 @@ class RelevantPath extends Path {
864864
}
865865
}
866866

867+
private predicate isModule(ItemNode m) { m instanceof Module }
868+
869+
/** Holds if root module `root` contains the module `m`. */
870+
private predicate rootHasModule(ItemNode root, ItemNode m) =
871+
doublyBoundedFastTC(hasChild/2, isRoot/1, isModule/1)(root, m)
872+
873+
pragma[nomagic]
874+
private ItemNode getOuterScope(ItemNode i) {
875+
// nested modules do not have unqualified access to items from outer modules,
876+
// except for items declared at top-level in the root module
877+
rootHasModule(result, i)
878+
or
879+
not i instanceof Module and
880+
result = i.getImmediateParent()
881+
}
882+
883+
pragma[nomagic]
884+
private ItemNode getAdjustedEnclosing(ItemNode encl0, Namespace ns) {
885+
// functions in `impl` blocks need to use explicit `Self::` to access other
886+
// functions in the `impl` block
887+
if encl0 instanceof ImplOrTraitItemNode and ns.isValue()
888+
then result = encl0.getImmediateParent()
889+
else result = encl0
890+
}
891+
867892
/**
868893
* Holds if the unqualified path `p` references an item named `name`, and `name`
869894
* may be looked up in the `ns` namespace inside enclosing item `encl`.
870895
*/
871896
pragma[nomagic]
872-
private predicate unqualifiedPathLookup(RelevantPath p, string name, Namespace ns, ItemNode encl) {
873-
exists(ItemNode encl0 |
897+
private predicate unqualifiedPathLookup(ItemNode encl, string name, Namespace ns, RelevantPath p) {
898+
exists(ItemNode encl0 | encl = getAdjustedEnclosing(encl0, ns) |
874899
// lookup in the immediately enclosing item
875900
p.isUnqualified(name) and
876901
encl0.getADescendant() = p and
877902
exists(ns) and
878-
not name = ["crate", "$crate"]
903+
not name = ["crate", "$crate", "super", "self"]
879904
or
880905
// lookup in an outer scope, but only if the item is not declared in inner scope
881906
exists(ItemNode mid |
882-
unqualifiedPathLookup(p, name, ns, mid) and
907+
unqualifiedPathLookup(mid, name, ns, p) and
883908
not declares(mid, ns, name) and
884-
not name = ["super", "self"] and
885909
not (
886910
name = "Self" and
887911
mid = any(ImplOrTraitItemNode i).getAnItemInSelfScope()
888-
)
889-
|
890-
// nested modules do not have unqualified access to items from outer modules,
891-
// except for items declared at top-level in the root module
892-
if mid instanceof Module
893-
then encl0 = mid.getImmediateParent+() and encl0.(ModuleLikeNode).isRoot()
894-
else encl0 = mid.getImmediateParent()
912+
) and
913+
encl0 = getOuterScope(mid)
895914
)
896-
|
897-
// functions in `impl` blocks need to use explicit `Self::` to access other
898-
// functions in the `impl` block
899-
if encl0 instanceof ImplOrTraitItemNode and ns.isValue()
900-
then encl = encl0.getImmediateParent()
901-
else encl = encl0
902915
)
903916
}
904917

@@ -917,24 +930,34 @@ private predicate hasChild(ItemNode parent, ItemNode child) { child.getImmediate
917930
private predicate rootHasCratePathTc(ItemNode i1, ItemNode i2) =
918931
doublyBoundedFastTC(hasChild/2, isRoot/1, hasCratePath/1)(i1, i2)
919932

933+
/**
934+
* Holds if the unqualified path `p` references a keyword item named `name`, and
935+
* `name` may be looked up in the `ns` namespace inside enclosing item `encl`.
936+
*/
920937
pragma[nomagic]
921-
private predicate unqualifiedPathLookup1(RelevantPath p, string name, Namespace ns, ItemNode encl) {
922-
unqualifiedPathLookup(p, name, ns, encl)
923-
or
938+
private predicate keywordLookup(ItemNode encl, string name, Namespace ns, RelevantPath p) {
924939
// For `($)crate`, jump directly to the root module
925940
exists(ItemNode i | p.isCratePath(name, i) |
926941
encl.(ModuleLikeNode).isRoot() and
927942
encl = i
928943
or
929944
rootHasCratePathTc(encl, i)
930945
)
946+
or
947+
name = ["super", "self"] and
948+
p.isUnqualified(name) and
949+
exists(ItemNode encl0 |
950+
encl0.getADescendant() = p and
951+
encl = getAdjustedEnclosing(encl0, ns)
952+
)
931953
}
932954

933955
pragma[nomagic]
934-
private ItemNode unqualifiedPathLookup(RelevantPath path, Namespace ns) {
935-
exists(ItemNode encl, string name |
936-
result = getASuccessor(encl, name, ns) and
937-
unqualifiedPathLookup1(path, name, ns, encl)
956+
private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns) {
957+
exists(ItemNode encl, string name | result = getASuccessor(encl, name, ns) |
958+
unqualifiedPathLookup(encl, name, ns, p)
959+
or
960+
keywordLookup(encl, name, ns, p)
938961
)
939962
}
940963

0 commit comments

Comments
 (0)