Skip to content

Commit 389f15e

Browse files
authored
Merge pull request #19362 from hvitved/rust/crate-extraction-workarounds
Rust: Crate graph extraction workarounds
2 parents 8ebbfb1 + 52bd99b commit 389f15e

File tree

2 files changed

+61
-15
lines changed

2 files changed

+61
-15
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ module Stages {
120120
or
121121
exists(resolvePath(_))
122122
or
123-
exists(any(ItemNode i).getASuccessor(_))
123+
exists(any(ItemNode i).getASuccessorFull(_))
124124
or
125125
exists(any(ItemNode i).getASuccessorRec(_))
126126
or

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

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,14 @@ abstract class ItemNode extends Locatable {
172172
result = this.(TypeParamItemNode).resolveABound().getASuccessorRec(name).(AssocItemNode)
173173
}
174174

175-
/** Gets a successor named `name` of this item, if any. */
175+
/**
176+
* Gets a successor named `name` of this item, if any.
177+
*
178+
* Whenever a function exists in both source code and in library code,
179+
* both are included
180+
*/
176181
cached
177-
ItemNode getASuccessor(string name) {
182+
ItemNode getASuccessorFull(string name) {
178183
Stages::PathResolutionStage::ref() and
179184
result = this.getASuccessorRec(name)
180185
or
@@ -202,6 +207,22 @@ abstract class ItemNode extends Locatable {
202207
result.(CrateItemNode).isPotentialDollarCrateTarget()
203208
}
204209

210+
/** Gets a successor named `name` of this item, if any. */
211+
pragma[nomagic]
212+
ItemNode getASuccessor(string name) {
213+
result = this.getASuccessorFull(name) and
214+
(
215+
// when a function exists in both source code and in library code, it is because
216+
// we also extracted the source code as library code, and hence we only want
217+
// the function from source code
218+
result.fromSource()
219+
or
220+
not result instanceof Function
221+
or
222+
not this.getASuccessorFull(name).(Function).fromSource()
223+
)
224+
}
225+
205226
/** Gets the location of this item. */
206227
Location getLocation() { result = super.getLocation() }
207228
}
@@ -234,7 +255,7 @@ abstract private class ModuleLikeNode extends ItemNode {
234255
private class SourceFileItemNode extends ModuleLikeNode, SourceFile {
235256
pragma[nomagic]
236257
ModuleLikeNode getSuper() {
237-
result = any(ModuleItemNode mod | fileImport(mod, this)).getASuccessor("super")
258+
result = any(ModuleItemNode mod | fileImport(mod, this)).getASuccessorFull("super")
238259
}
239260

240261
override string getName() { result = "(source file)" }
@@ -297,7 +318,7 @@ class CrateItemNode extends ItemNode instanceof Crate {
297318
predicate isPotentialDollarCrateTarget() {
298319
exists(string name, RelevantPath p |
299320
p.isDollarCrateQualifiedPath(name) and
300-
exists(this.getASuccessor(name))
321+
exists(this.getASuccessorFull(name))
301322
)
302323
}
303324

@@ -323,7 +344,14 @@ abstract private class AssocItemNode extends ItemNode, AssocItem {
323344
private class ConstItemNode extends AssocItemNode instanceof Const {
324345
override string getName() { result = Const.super.getName().getText() }
325346

326-
override predicate hasImplementation() { super.hasBody() }
347+
override predicate hasImplementation() {
348+
super.hasBody()
349+
or
350+
// for trait items from library code, we do not currently know if they
351+
// have default implementations or not, so we assume they do
352+
not this.fromSource() and
353+
this = any(TraitItemNode t).getAnAssocItem()
354+
}
327355

328356
override Namespace getNamespace() { result.isValue() }
329357

@@ -359,7 +387,14 @@ private class VariantItemNode extends ItemNode instanceof Variant {
359387
class FunctionItemNode extends AssocItemNode instanceof Function {
360388
override string getName() { result = Function.super.getName().getText() }
361389

362-
override predicate hasImplementation() { super.hasBody() }
390+
override predicate hasImplementation() {
391+
super.hasBody()
392+
or
393+
// for trait items from library code, we do not currently know if they
394+
// have default implementations or not, so we assume they do
395+
not this.fromSource() and
396+
this = any(TraitItemNode t).getAnAssocItem()
397+
}
363398

364399
override Namespace getNamespace() { result.isValue() }
365400

@@ -862,6 +897,12 @@ class RelevantPath extends Path {
862897
this.getQualifier().(RelevantPath).isCratePath("$crate", _) and
863898
this.getText() = name
864899
}
900+
901+
// TODO: Remove once the crate graph extractor generates publicly visible paths
902+
predicate requiresExtractorWorkaround() {
903+
not this.fromSource() and
904+
this = any(RelevantPath p).getQualifier()
905+
}
865906
}
866907

867908
private predicate isModule(ItemNode m) { m instanceof Module }
@@ -916,8 +957,8 @@ private predicate unqualifiedPathLookup(ItemNode encl, string name, Namespace ns
916957
}
917958

918959
pragma[nomagic]
919-
private ItemNode getASuccessor(ItemNode pred, string name, Namespace ns) {
920-
result = pred.getASuccessor(name) and
960+
private ItemNode getASuccessorFull(ItemNode pred, string name, Namespace ns) {
961+
result = pred.getASuccessorFull(name) and
921962
ns = result.getNamespace()
922963
}
923964

@@ -954,7 +995,7 @@ private predicate keywordLookup(ItemNode encl, string name, Namespace ns, Releva
954995

955996
pragma[nomagic]
956997
private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns) {
957-
exists(ItemNode encl, string name | result = getASuccessor(encl, name, ns) |
998+
exists(ItemNode encl, string name | result = getASuccessorFull(encl, name, ns) |
958999
unqualifiedPathLookup(encl, name, ns, p)
9591000
or
9601001
keywordLookup(encl, name, ns, p)
@@ -978,7 +1019,7 @@ private ItemNode resolvePath0(RelevantPath path, Namespace ns) {
9781019
or
9791020
exists(ItemNode q, string name |
9801021
q = resolvePathQualifier(path, name) and
981-
result = getASuccessor(q, name, ns)
1022+
result = getASuccessorFull(q, name, ns)
9821023
)
9831024
or
9841025
result = resolveUseTreeListItem(_, _, path) and
@@ -1029,6 +1070,7 @@ pragma[nomagic]
10291070
private ItemNode resolvePathPrivate(
10301071
RelevantPath path, ModuleLikeNode itemParent, ModuleLikeNode pathParent
10311072
) {
1073+
not path.requiresExtractorWorkaround() and
10321074
result = resolvePath1(path) and
10331075
itemParent = result.getImmediateParentModule() and
10341076
not result.isPublic() and
@@ -1062,7 +1104,11 @@ private ModuleLikeNode getAPrivateVisibleModule(ModuleLikeNode itemParent) {
10621104
cached
10631105
ItemNode resolvePath(RelevantPath path) {
10641106
result = resolvePath1(path) and
1065-
result.isPublic()
1107+
(
1108+
result.isPublic()
1109+
or
1110+
path.requiresExtractorWorkaround()
1111+
)
10661112
or
10671113
exists(ModuleLikeNode itemParent, ModuleLikeNode pathParent |
10681114
result = resolvePathPrivate(path, itemParent, pathParent) and
@@ -1098,12 +1144,12 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
10981144
mid = resolveUseTreeListItem(use, midTree) and
10991145
tree = midTree.getUseTreeList().getAUseTree() and
11001146
isUseTreeSubPathUnqualified(tree, path, pragma[only_bind_into](name)) and
1101-
result = mid.getASuccessor(pragma[only_bind_into](name))
1147+
result = mid.getASuccessorFull(pragma[only_bind_into](name))
11021148
)
11031149
or
11041150
exists(ItemNode q, string name |
11051151
q = resolveUseTreeListItemQualifier(use, tree, path, name) and
1106-
result = q.getASuccessor(name)
1152+
result = q.getASuccessorFull(name)
11071153
)
11081154
}
11091155

@@ -1133,7 +1179,7 @@ private predicate useImportEdge(Use use, string name, ItemNode item) {
11331179
then
11341180
exists(ItemNode encl, Namespace ns |
11351181
encl.getADescendant() = use and
1136-
item = getASuccessor(used, name, ns) and
1182+
item = getASuccessorFull(used, name, ns) and
11371183
// glob imports can be shadowed
11381184
not declares(encl, ns, name) and
11391185
not name = ["super", "self", "Self", "$crate", "crate"]

0 commit comments

Comments
 (0)