Skip to content

Commit 70a160a

Browse files
committed
Rust: Crate graph extraction workarounds
1 parent f7021ab commit 70a160a

File tree

2 files changed

+67
-19
lines changed

2 files changed

+67
-19
lines changed

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

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,16 @@ abstract private class AssocItemNode extends ItemNode, AssocItem {
323323
private class ConstItemNode extends AssocItemNode instanceof Const {
324324
override string getName() { result = Const.super.getName().getText() }
325325

326-
override predicate hasImplementation() { super.hasBody() }
326+
override predicate hasImplementation() {
327+
super.hasBody()
328+
or
329+
// for trait items from library code, we do not currently know if they
330+
// have default implementations or not, so we assume they do
331+
exists(TraitItemNode t |
332+
this = t.getAnAssocItem() and
333+
not this.fromSource()
334+
)
335+
}
327336

328337
override Namespace getNamespace() { result.isValue() }
329338

@@ -359,7 +368,16 @@ private class VariantItemNode extends ItemNode instanceof Variant {
359368
class FunctionItemNode extends AssocItemNode instanceof Function {
360369
override string getName() { result = Function.super.getName().getText() }
361370

362-
override predicate hasImplementation() { super.hasBody() }
371+
override predicate hasImplementation() {
372+
super.hasBody()
373+
or
374+
// for trait items from library code, we do not currently know if they
375+
// have default implementations or not, so we assume they do
376+
exists(TraitItemNode t |
377+
this = t.getAnAssocItem() and
378+
not this.fromSource()
379+
)
380+
}
363381

364382
override Namespace getNamespace() { result.isValue() }
365383

@@ -862,6 +880,12 @@ class RelevantPath extends Path {
862880
this.getQualifier().(RelevantPath).isCratePath("$crate", _) and
863881
this.getText() = name
864882
}
883+
884+
// TODO: Remove once the crate graph extractor generates publicly visible paths
885+
predicate requiresExtractorWorkaround() {
886+
not this.fromSource() and
887+
this = any(RelevantPath p).getQualifier()
888+
}
865889
}
866890

867891
private predicate isModule(ItemNode m) { m instanceof Module }
@@ -1029,6 +1053,7 @@ pragma[nomagic]
10291053
private ItemNode resolvePathPrivate(
10301054
RelevantPath path, ModuleLikeNode itemParent, ModuleLikeNode pathParent
10311055
) {
1056+
not path.requiresExtractorWorkaround() and
10321057
result = resolvePath1(path) and
10331058
itemParent = result.getImmediateParentModule() and
10341059
not result.isPublic() and
@@ -1062,7 +1087,11 @@ private ModuleLikeNode getAPrivateVisibleModule(ModuleLikeNode itemParent) {
10621087
cached
10631088
ItemNode resolvePath(RelevantPath path) {
10641089
result = resolvePath1(path) and
1065-
result.isPublic()
1090+
(
1091+
result.isPublic()
1092+
or
1093+
path.requiresExtractorWorkaround()
1094+
)
10661095
or
10671096
exists(ModuleLikeNode itemParent, ModuleLikeNode pathParent |
10681097
result = resolvePathPrivate(path, itemParent, pathParent) and

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

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,26 @@ newtype TType =
2929
abstract class Type extends TType {
3030
/** Gets the method `name` belonging to this type, if any. */
3131
pragma[nomagic]
32-
abstract Function getMethod(string name);
32+
final Function getMethod(string name) {
33+
result = this.getAMethod(name) and
34+
(
35+
// when a method exists in both source code and in library code, it is because
36+
// we also extracted the source code as library code, and hence we only want
37+
// the method from source code
38+
result.fromSource()
39+
or
40+
not this.getAMethod(name).fromSource()
41+
)
42+
}
43+
44+
/**
45+
* Gets a method `name` belonging to this type, if any.
46+
*
47+
* Multiple methods may exist with the same name when it exists in both
48+
* source code and in library code.
49+
*/
50+
pragma[nomagic]
51+
abstract Function getAMethod(string name);
3352

3453
/** Gets the struct field `name` belonging to this type, if any. */
3554
pragma[nomagic]
@@ -75,7 +94,7 @@ abstract private class StructOrEnumType extends Type {
7594
abstract ItemNode asItemNode();
7695

7796
pragma[nomagic]
78-
private Function getMethodCand(ImplOrTraitItemNode impl, string name) {
97+
private Function getAMethodCand(ImplOrTraitItemNode impl, string name) {
7998
result = this.asItemNode().getASuccessor(name) and
8099
result = impl.getAnAssocItem() and
81100
(
@@ -86,17 +105,17 @@ abstract private class StructOrEnumType extends Type {
86105
}
87106

88107
pragma[nomagic]
89-
private Function getImplMethod(ImplOrTraitItemNode impl, string name) {
90-
result = this.getMethodCand(impl, name) and
108+
private Function getAnImplMethod(ImplOrTraitItemNode impl, string name) {
109+
result = this.getAMethodCand(impl, name) and
91110
impl = any(Impl i | not i.hasTrait())
92111
}
93112

94-
final override Function getMethod(string name) {
95-
result = this.getImplMethod(_, name)
113+
final override Function getAMethod(string name) {
114+
result = this.getAnImplMethod(_, name)
96115
or
97116
// methods from `impl` blocks shadow functions from `impl Trait` blocks
98-
result = this.getMethodCand(_, name) and
99-
not exists(this.getImplMethod(_, name))
117+
result = this.getAMethodCand(_, name) and
118+
not exists(this.getAnImplMethod(_, name))
100119
}
101120

102121
/** Gets all of the fully parametric `impl` blocks that target this type. */
@@ -154,7 +173,7 @@ class TraitType extends Type, TTrait {
154173

155174
TraitType() { this = TTrait(trait) }
156175

157-
override Function getMethod(string name) { result = trait.(ItemNode).getASuccessor(name) }
176+
override Function getAMethod(string name) { result = trait.(ItemNode).getASuccessor(name) }
158177

159178
override StructField getStructField(string name) { none() }
160179

@@ -236,7 +255,7 @@ class ImplType extends Type, TImpl {
236255

237256
ImplType() { this = TImpl(impl) }
238257

239-
override Function getMethod(string name) { result = impl.(ItemNode).getASuccessor(name) }
258+
override Function getAMethod(string name) { result = impl.(ItemNode).getASuccessor(name) }
240259

241260
override StructField getStructField(string name) { none() }
242261

@@ -263,7 +282,7 @@ class ImplType extends Type, TImpl {
263282
class ArrayType extends Type, TArrayType {
264283
ArrayType() { this = TArrayType() }
265284

266-
override Function getMethod(string name) { none() }
285+
override Function getAMethod(string name) { none() }
267286

268287
override StructField getStructField(string name) { none() }
269288

@@ -289,7 +308,7 @@ class ArrayType extends Type, TArrayType {
289308
class RefType extends Type, TRefType {
290309
RefType() { this = TRefType() }
291310

292-
override Function getMethod(string name) { none() }
311+
override Function getAMethod(string name) { none() }
293312

294313
override StructField getStructField(string name) { none() }
295314

@@ -334,7 +353,7 @@ class TypeParamTypeParameter extends TypeParameter, TTypeParamTypeParameter {
334353

335354
TypeParam getTypeParam() { result = typeParam }
336355

337-
override Function getMethod(string name) {
356+
override Function getAMethod(string name) {
338357
// NOTE: If the type parameter has trait bounds, then this finds methods
339358
// on the bounding traits.
340359
result = typeParam.(ItemNode).getASuccessor(name)
@@ -393,7 +412,7 @@ class AssociatedTypeTypeParameter extends TypeParameter, TAssociatedTypeTypePara
393412

394413
int getIndex() { traitAliasIndex(_, result, typeAlias) }
395414

396-
override Function getMethod(string name) { none() }
415+
override Function getAMethod(string name) { none() }
397416

398417
override string toString() { result = typeAlias.getName().getText() }
399418

@@ -404,7 +423,7 @@ class AssociatedTypeTypeParameter extends TypeParameter, TAssociatedTypeTypePara
404423

405424
/** An implicit reference type parameter. */
406425
class RefTypeParameter extends TypeParameter, TRefTypeParameter {
407-
override Function getMethod(string name) { none() }
426+
override Function getAMethod(string name) { none() }
408427

409428
override string toString() { result = "&T" }
410429

@@ -427,7 +446,7 @@ class SelfTypeParameter extends TypeParameter, TSelfTypeParameter {
427446

428447
override TypeMention getABaseTypeMention() { result = trait }
429448

430-
override Function getMethod(string name) {
449+
override Function getAMethod(string name) {
431450
// The `Self` type parameter is an implementation of the trait, so it has
432451
// all the trait's methods.
433452
result = trait.(ItemNode).getASuccessor(name)

0 commit comments

Comments
 (0)