Rust: Remove source/library deduplication in path resolution

This commit is contained in:
Tom Hvitved
2025-08-08 13:28:18 +02:00
parent 72563ec5a4
commit c043e30d46
2 changed files with 11 additions and 32 deletions

View File

@@ -120,7 +120,7 @@ module Stages {
or or
exists(resolvePath(_)) exists(resolvePath(_))
or or
exists(any(ItemNode i).getASuccessorFull(_)) exists(any(ItemNode i).getASuccessor(_))
or or
exists(any(ItemNode i).getASuccessorRec(_)) exists(any(ItemNode i).getASuccessorRec(_))
or or

View File

@@ -194,7 +194,7 @@ abstract class ItemNode extends Locatable {
* both are included * both are included
*/ */
cached cached
ItemNode getASuccessorFull(string name) { ItemNode getASuccessor(string name) {
Stages::PathResolutionStage::ref() and Stages::PathResolutionStage::ref() and
result = this.getASuccessorRec(name) result = this.getASuccessorRec(name)
or or
@@ -261,27 +261,6 @@ abstract class ItemNode extends Locatable {
item instanceof TypeParamItemNode item instanceof TypeParamItemNode
} }
pragma[nomagic]
private predicate hasSourceFunction(string name) {
this.getASuccessorFull(name).(Function).fromSource()
}
/** Gets a successor named `name` of this item, if any. */
pragma[nomagic]
ItemNode getASuccessor(string name) {
result = this.getASuccessorFull(name) and
(
// when a function exists in both source code and in library code, it is because
// we also extracted the source code as library code, and hence we only want
// the function from source code
result.fromSource()
or
not result instanceof Function
or
not this.hasSourceFunction(name)
)
}
/** Holds if this item has a canonical path belonging to the crate `c`. */ /** Holds if this item has a canonical path belonging to the crate `c`. */
abstract predicate hasCanonicalPath(Crate c); abstract predicate hasCanonicalPath(Crate c);
@@ -345,7 +324,7 @@ abstract private class ModuleLikeNode extends ItemNode {
private class SourceFileItemNode extends ModuleLikeNode, SourceFile { private class SourceFileItemNode extends ModuleLikeNode, SourceFile {
pragma[nomagic] pragma[nomagic]
ModuleLikeNode getSuper() { ModuleLikeNode getSuper() {
result = any(ModuleItemNode mod | fileImport(mod, this)).getASuccessorFull("super") result = any(ModuleItemNode mod | fileImport(mod, this)).getASuccessor("super")
} }
override string getName() { result = "(source file)" } override string getName() { result = "(source file)" }
@@ -393,7 +372,7 @@ class CrateItemNode extends ItemNode instanceof Crate {
predicate isPotentialDollarCrateTarget() { predicate isPotentialDollarCrateTarget() {
exists(string name, RelevantPath p | exists(string name, RelevantPath p |
p.isDollarCrateQualifiedPath(name) and p.isDollarCrateQualifiedPath(name) and
exists(this.getASuccessorFull(name)) exists(this.getASuccessor(name))
) )
} }
@@ -1245,8 +1224,8 @@ private predicate unqualifiedPathLookup(ItemNode encl, string name, Namespace ns
} }
pragma[nomagic] pragma[nomagic]
private ItemNode getASuccessorFull(ItemNode pred, string name, Namespace ns) { private ItemNode getASuccessor(ItemNode pred, string name, Namespace ns) {
result = pred.getASuccessorFull(name) and result = pred.getASuccessor(name) and
ns = result.getNamespace() ns = result.getNamespace()
} }
@@ -1281,7 +1260,7 @@ private predicate keywordLookup(ItemNode encl, string name, RelevantPath p) {
pragma[nomagic] pragma[nomagic]
private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns) { private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns) {
exists(ItemNode encl, string name | exists(ItemNode encl, string name |
result = getASuccessorFull(encl, name, ns) and not encl.excludedLocally(name, result) result = getASuccessor(encl, name, ns) and not encl.excludedLocally(name, result)
| |
unqualifiedPathLookup(encl, name, ns, p) unqualifiedPathLookup(encl, name, ns, p)
or or
@@ -1306,7 +1285,7 @@ private ItemNode resolvePath0(RelevantPath path, Namespace ns) {
or or
exists(ItemNode q, string name | exists(ItemNode q, string name |
q = resolvePathQualifier(path, name) and q = resolvePathQualifier(path, name) and
result = getASuccessorFull(q, name, ns) and result = getASuccessor(q, name, ns) and
not q.excludedExternally(name, result) not q.excludedExternally(name, result)
) )
or or
@@ -1383,12 +1362,12 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
mid = resolveUseTreeListItem(use, midTree) and mid = resolveUseTreeListItem(use, midTree) and
tree = midTree.getUseTreeList().getAUseTree() and tree = midTree.getUseTreeList().getAUseTree() and
isUseTreeSubPathUnqualified(tree, path, pragma[only_bind_into](name)) and isUseTreeSubPathUnqualified(tree, path, pragma[only_bind_into](name)) and
result = mid.getASuccessorFull(pragma[only_bind_into](name)) result = mid.getASuccessor(pragma[only_bind_into](name))
) )
or or
exists(ItemNode q, string name | exists(ItemNode q, string name |
q = resolveUseTreeListItemQualifier(use, tree, path, name) and q = resolveUseTreeListItemQualifier(use, tree, path, name) and
result = q.getASuccessorFull(name) result = q.getASuccessor(name)
) )
} }
@@ -1418,7 +1397,7 @@ private predicate useImportEdge(Use use, string name, ItemNode item) {
then then
exists(ItemNode encl, Namespace ns | exists(ItemNode encl, Namespace ns |
encl.getADescendant() = use and encl.getADescendant() = use and
item = getASuccessorFull(used, name, ns) and item = getASuccessor(used, name, ns) and
// glob imports can be shadowed // glob imports can be shadowed
not declares(encl, ns, name) and not declares(encl, ns, name) and
not name = ["super", "self", "Self", "$crate", "crate"] not name = ["super", "self", "Self", "$crate", "crate"]