-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Rust: Path resolution associated type fix #20096
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
71a5e41
ac6715f
8ebebf0
2885046
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -112,13 +112,18 @@ abstract class ItemNode extends Locatable { | |||||||||||||||||||||||||||||||||||||||||||||||||
result = this.(SourceFileItemNode).getSuper() | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
pragma[nomagic] | ||||||||||||||||||||||||||||||||||||||||||||||||||
private ItemNode getAChildSuccessor(string name) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
this = result.getImmediateParent() and | ||||||||||||||||||||||||||||||||||||||||||||||||||
name = result.getName() | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
cached | ||||||||||||||||||||||||||||||||||||||||||||||||||
ItemNode getASuccessorRec(string name) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
Stages::PathResolutionStage::ref() and | ||||||||||||||||||||||||||||||||||||||||||||||||||
sourceFileEdge(this, name, result) | ||||||||||||||||||||||||||||||||||||||||||||||||||
or | ||||||||||||||||||||||||||||||||||||||||||||||||||
this = result.getImmediateParent() and | ||||||||||||||||||||||||||||||||||||||||||||||||||
name = result.getName() | ||||||||||||||||||||||||||||||||||||||||||||||||||
result = this.getAChildSuccessor(name) | ||||||||||||||||||||||||||||||||||||||||||||||||||
or | ||||||||||||||||||||||||||||||||||||||||||||||||||
fileImportEdge(this, name, result) | ||||||||||||||||||||||||||||||||||||||||||||||||||
or | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -224,6 +229,38 @@ abstract class ItemNode extends Locatable { | |||||||||||||||||||||||||||||||||||||||||||||||||
result.(CrateItemNode).isPotentialDollarCrateTarget() | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||
* Holds if the successor `item` with the name `name` is not available locally | ||||||||||||||||||||||||||||||||||||||||||||||||||
* for unqualified paths. | ||||||||||||||||||||||||||||||||||||||||||||||||||
* | ||||||||||||||||||||||||||||||||||||||||||||||||||
* This has the effect that a path of the form `name` inside `this` will not | ||||||||||||||||||||||||||||||||||||||||||||||||||
* resolve to `item`. | ||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||
pragma[nomagic] | ||||||||||||||||||||||||||||||||||||||||||||||||||
predicate excludedLocally(string name, ItemNode item) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
// Associated items in an impl or trait block are not directly available | ||||||||||||||||||||||||||||||||||||||||||||||||||
// inside the block, they require a qualified path with a `Self` prefix. | ||||||||||||||||||||||||||||||||||||||||||||||||||
item = this.getAChildSuccessor(name) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
this instanceof ImplOrTraitItemNode and | ||||||||||||||||||||||||||||||||||||||||||||||||||
item instanceof AssocItemNode | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||
* Holds if the successor `item` with the name `name` is not available | ||||||||||||||||||||||||||||||||||||||||||||||||||
* externally for qualified paths that resolve to this item. | ||||||||||||||||||||||||||||||||||||||||||||||||||
* | ||||||||||||||||||||||||||||||||||||||||||||||||||
* This has the effect that a path of the form `Qualifier::name`, where | ||||||||||||||||||||||||||||||||||||||||||||||||||
* `Qualifier` resolves to this item, will not resolve to `item`. | ||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||
pragma[nomagic] | ||||||||||||||||||||||||||||||||||||||||||||||||||
predicate excludedExternally(string name, ItemNode item) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
// Type parameters for an `impl` or trait block are not available outside of | ||||||||||||||||||||||||||||||||||||||||||||||||||
// the block. | ||||||||||||||||||||||||||||||||||||||||||||||||||
item = this.getAChildSuccessor(name) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
this instanceof ImplOrTraitItemNode and | ||||||||||||||||||||||||||||||||||||||||||||||||||
item instanceof TypeParamItemNode | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
pragma[nomagic] | ||||||||||||||||||||||||||||||||||||||||||||||||||
private predicate hasSourceFunction(string name) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
this.getASuccessorFull(name).(Function).fromSource() | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1145,7 +1182,9 @@ pragma[nomagic] | |||||||||||||||||||||||||||||||||||||||||||||||||
private predicate declares(ItemNode item, Namespace ns, string name) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
exists(ItemNode child | child.getImmediateParent() = item | | ||||||||||||||||||||||||||||||||||||||||||||||||||
child.getName() = name and | ||||||||||||||||||||||||||||||||||||||||||||||||||
child.getNamespace() = ns | ||||||||||||||||||||||||||||||||||||||||||||||||||
child.getNamespace() = ns and | ||||||||||||||||||||||||||||||||||||||||||||||||||
// If `item` is excluded locally then it does not declare `name`. | ||||||||||||||||||||||||||||||||||||||||||||||||||
not item.excludedLocally(name, child) | ||||||||||||||||||||||||||||||||||||||||||||||||||
or | ||||||||||||||||||||||||||||||||||||||||||||||||||
useTreeDeclares(child.(Use).getUseTree(), name) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
exists(ns) // `use foo::bar` can refer to both a value and a type | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1193,38 +1232,27 @@ private ItemNode getOuterScope(ItemNode i) { | |||||||||||||||||||||||||||||||||||||||||||||||||
result = i.getImmediateParent() | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
pragma[nomagic] | ||||||||||||||||||||||||||||||||||||||||||||||||||
private ItemNode getAdjustedEnclosing(ItemNode encl0, Namespace ns) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
// functions in `impl` blocks need to use explicit `Self::` to access other | ||||||||||||||||||||||||||||||||||||||||||||||||||
// functions in the `impl` block | ||||||||||||||||||||||||||||||||||||||||||||||||||
if encl0 instanceof ImplOrTraitItemNode and ns.isValue() | ||||||||||||||||||||||||||||||||||||||||||||||||||
then result = encl0.getImmediateParent() | ||||||||||||||||||||||||||||||||||||||||||||||||||
else result = encl0 | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||
* Holds if the unqualified path `p` references an item named `name`, and `name` | ||||||||||||||||||||||||||||||||||||||||||||||||||
* may be looked up in the `ns` namespace inside enclosing item `encl`. | ||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||
pragma[nomagic] | ||||||||||||||||||||||||||||||||||||||||||||||||||
private predicate unqualifiedPathLookup(ItemNode encl, string name, Namespace ns, RelevantPath p) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
exists(ItemNode encl0 | encl = getAdjustedEnclosing(encl0, ns) | | ||||||||||||||||||||||||||||||||||||||||||||||||||
// lookup in the immediately enclosing item | ||||||||||||||||||||||||||||||||||||||||||||||||||
p.isUnqualified(name) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
encl0.getADescendant() = p and | ||||||||||||||||||||||||||||||||||||||||||||||||||
exists(ns) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
not name = ["crate", "$crate", "super", "self"] | ||||||||||||||||||||||||||||||||||||||||||||||||||
or | ||||||||||||||||||||||||||||||||||||||||||||||||||
// lookup in an outer scope, but only if the item is not declared in inner scope | ||||||||||||||||||||||||||||||||||||||||||||||||||
exists(ItemNode mid | | ||||||||||||||||||||||||||||||||||||||||||||||||||
unqualifiedPathLookup(mid, name, ns, p) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
not declares(mid, ns, name) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
not ( | ||||||||||||||||||||||||||||||||||||||||||||||||||
name = "Self" and | ||||||||||||||||||||||||||||||||||||||||||||||||||
mid = any(ImplOrTraitItemNode i).getAnItemInSelfScope() | ||||||||||||||||||||||||||||||||||||||||||||||||||
) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
encl0 = getOuterScope(mid) | ||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||
// lookup in the immediately enclosing item | ||||||||||||||||||||||||||||||||||||||||||||||||||
p.isUnqualified(name) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
encl.getADescendant() = p and | ||||||||||||||||||||||||||||||||||||||||||||||||||
exists(ns) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
not name = ["crate", "$crate", "super", "self"] | ||||||||||||||||||||||||||||||||||||||||||||||||||
or | ||||||||||||||||||||||||||||||||||||||||||||||||||
// lookup in an outer scope, but only if the item is not declared in inner scope | ||||||||||||||||||||||||||||||||||||||||||||||||||
exists(ItemNode mid | | ||||||||||||||||||||||||||||||||||||||||||||||||||
unqualifiedPathLookup(mid, name, ns, p) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
not declares(mid, ns, name) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
not ( | ||||||||||||||||||||||||||||||||||||||||||||||||||
name = "Self" and | ||||||||||||||||||||||||||||||||||||||||||||||||||
mid = any(ImplOrTraitItemNode i).getAnItemInSelfScope() | ||||||||||||||||||||||||||||||||||||||||||||||||||
) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
encl = getOuterScope(mid) | ||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1245,10 +1273,10 @@ private predicate sourceFileHasCratePathTc(ItemNode i1, ItemNode i2) = | |||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||
* Holds if the unqualified path `p` references a keyword item named `name`, and | ||||||||||||||||||||||||||||||||||||||||||||||||||
* `name` may be looked up in the `ns` namespace inside enclosing item `encl`. | ||||||||||||||||||||||||||||||||||||||||||||||||||
* `name` may be looked up inside enclosing item `encl`. | ||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||
pragma[nomagic] | ||||||||||||||||||||||||||||||||||||||||||||||||||
private predicate keywordLookup(ItemNode encl, string name, Namespace ns, RelevantPath p) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
private predicate keywordLookup(ItemNode encl, string name, RelevantPath p) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
// For `($)crate`, jump directly to the root module | ||||||||||||||||||||||||||||||||||||||||||||||||||
exists(ItemNode i | p.isCratePath(name, i) | | ||||||||||||||||||||||||||||||||||||||||||||||||||
encl instanceof SourceFile and | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1259,18 +1287,17 @@ private predicate keywordLookup(ItemNode encl, string name, Namespace ns, Releva | |||||||||||||||||||||||||||||||||||||||||||||||||
or | ||||||||||||||||||||||||||||||||||||||||||||||||||
name = ["super", "self"] and | ||||||||||||||||||||||||||||||||||||||||||||||||||
p.isUnqualified(name) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
exists(ItemNode encl0 | | ||||||||||||||||||||||||||||||||||||||||||||||||||
encl0.getADescendant() = p and | ||||||||||||||||||||||||||||||||||||||||||||||||||
encl = getAdjustedEnclosing(encl0, ns) | ||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||
encl.getADescendant() = p | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
pragma[nomagic] | ||||||||||||||||||||||||||||||||||||||||||||||||||
private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
exists(ItemNode encl, string name | result = getASuccessorFull(encl, name, ns) | | ||||||||||||||||||||||||||||||||||||||||||||||||||
exists(ItemNode encl, string name | | ||||||||||||||||||||||||||||||||||||||||||||||||||
result = getASuccessorFull(encl, name, ns) and not encl.excludedLocally(name, result) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| | ||||||||||||||||||||||||||||||||||||||||||||||||||
unqualifiedPathLookup(encl, name, ns, p) | ||||||||||||||||||||||||||||||||||||||||||||||||||
or | ||||||||||||||||||||||||||||||||||||||||||||||||||
keywordLookup(encl, name, ns, p) | ||||||||||||||||||||||||||||||||||||||||||||||||||
keywordLookup(encl, name, p) and exists(ns) | ||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1291,7 +1318,8 @@ private ItemNode resolvePath0(RelevantPath path, Namespace ns) { | |||||||||||||||||||||||||||||||||||||||||||||||||
or | ||||||||||||||||||||||||||||||||||||||||||||||||||
exists(ItemNode q, string name | | ||||||||||||||||||||||||||||||||||||||||||||||||||
q = resolvePathQualifier(path, name) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
result = getASuccessorFull(q, name, ns) | ||||||||||||||||||||||||||||||||||||||||||||||||||
result = getASuccessorFull(q, name, ns) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
not q.excludedExternally(name, result) | ||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||
or | ||||||||||||||||||||||||||||||||||||||||||||||||||
result = resolveUseTreeListItem(_, _, path) and | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new
getAChildSuccessor
predicate lacks documentation explaining its purpose and relationship to the existing successor methods.Copilot uses AI. Check for mistakes.