Skip to content

Commit 9753252

Browse files
committed
Rust: Crate graph extraction workarounds
1 parent 7106475 commit 9753252

File tree

2 files changed

+61
-13
lines changed

2 files changed

+61
-13
lines changed

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

+32-3
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

+29-10
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]
@@ -74,7 +93,7 @@ abstract class Type extends TType {
7493
abstract private class StructOrEnumType extends Type {
7594
abstract ItemNode asItemNode();
7695

77-
final override Function getMethod(string name) {
96+
final override Function getAMethod(string name) {
7897
result = this.asItemNode().getASuccessor(name) and
7998
exists(ImplOrTraitItemNode impl | result = impl.getAnAssocItem() |
8099
impl instanceof Trait
@@ -138,7 +157,7 @@ class TraitType extends Type, TTrait {
138157

139158
TraitType() { this = TTrait(trait) }
140159

141-
override Function getMethod(string name) { result = trait.(ItemNode).getASuccessor(name) }
160+
override Function getAMethod(string name) { result = trait.(ItemNode).getASuccessor(name) }
142161

143162
override StructField getStructField(string name) { none() }
144163

@@ -220,7 +239,7 @@ class ImplType extends Type, TImpl {
220239

221240
ImplType() { this = TImpl(impl) }
222241

223-
override Function getMethod(string name) { result = impl.(ItemNode).getASuccessor(name) }
242+
override Function getAMethod(string name) { result = impl.(ItemNode).getASuccessor(name) }
224243

225244
override StructField getStructField(string name) { none() }
226245

@@ -247,7 +266,7 @@ class ImplType extends Type, TImpl {
247266
class ArrayType extends Type, TArrayType {
248267
ArrayType() { this = TArrayType() }
249268

250-
override Function getMethod(string name) { none() }
269+
override Function getAMethod(string name) { none() }
251270

252271
override StructField getStructField(string name) { none() }
253272

@@ -273,7 +292,7 @@ class ArrayType extends Type, TArrayType {
273292
class RefType extends Type, TRefType {
274293
RefType() { this = TRefType() }
275294

276-
override Function getMethod(string name) { none() }
295+
override Function getAMethod(string name) { none() }
277296

278297
override StructField getStructField(string name) { none() }
279298

@@ -318,7 +337,7 @@ class TypeParamTypeParameter extends TypeParameter, TTypeParamTypeParameter {
318337

319338
TypeParam getTypeParam() { result = typeParam }
320339

321-
override Function getMethod(string name) {
340+
override Function getAMethod(string name) {
322341
// NOTE: If the type parameter has trait bounds, then this finds methods
323342
// on the bounding traits.
324343
result = typeParam.(ItemNode).getASuccessor(name)
@@ -377,7 +396,7 @@ class AssociatedTypeTypeParameter extends TypeParameter, TAssociatedTypeTypePara
377396

378397
int getIndex() { traitAliasIndex(_, result, typeAlias) }
379398

380-
override Function getMethod(string name) { none() }
399+
override Function getAMethod(string name) { none() }
381400

382401
override string toString() { result = typeAlias.getName().getText() }
383402

@@ -388,7 +407,7 @@ class AssociatedTypeTypeParameter extends TypeParameter, TAssociatedTypeTypePara
388407

389408
/** An implicit reference type parameter. */
390409
class RefTypeParameter extends TypeParameter, TRefTypeParameter {
391-
override Function getMethod(string name) { none() }
410+
override Function getAMethod(string name) { none() }
392411

393412
override string toString() { result = "&T" }
394413

@@ -411,7 +430,7 @@ class SelfTypeParameter extends TypeParameter, TSelfTypeParameter {
411430

412431
override TypeMention getABaseTypeMention() { result = trait }
413432

414-
override Function getMethod(string name) {
433+
override Function getAMethod(string name) {
415434
// The `Self` type parameter is an implementation of the trait, so it has
416435
// all the trait's methods.
417436
result = trait.(ItemNode).getASuccessor(name)

0 commit comments

Comments
 (0)