Skip to content

Commit 8a6c5e5

Browse files
committed
Rust: Model slice/array types in path resolution
1 parent bfa3562 commit 8a6c5e5

File tree

12 files changed

+4629
-4210
lines changed

12 files changed

+4629
-4210
lines changed

rust/ql/lib/codeql/rust/frameworks/stdlib/Builtins.qll

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,36 @@ class F32 extends FloatingPointTypeImpl {
136136
class F64 extends FloatingPointTypeImpl {
137137
F64() { this.getName() = "f64" }
138138
}
139+
140+
/** The builtin slice type `[T]`. */
141+
class SliceType extends BuiltinType {
142+
SliceType() { this.getName() = "Slice" }
143+
}
144+
145+
/** The builtin array type `[T; N]`. */
146+
class ArrayType extends BuiltinType {
147+
ArrayType() { this.getName() = "Array" }
148+
}
149+
150+
/** The builtin reference type `&T` or `&mut T`. */
151+
class RefType extends BuiltinType {
152+
RefType() { this.getName() = "Ref" }
153+
}
154+
155+
/** The builtin pointer type `*const T` or `*mut T`. */
156+
class PtrType extends BuiltinType {
157+
PtrType() { this.getName() = "Ptr" }
158+
}
159+
160+
/** A builtin tuple type `(T1, T2, ...)`. */
161+
class TupleType extends BuiltinType {
162+
TupleType() { this.getName().matches("Tuple%") }
163+
164+
/** Gets the arity of this tuple type. */
165+
int getArity() {
166+
not this.hasGenericParamList() and
167+
result = 0
168+
or
169+
result = this.getGenericParamList().getNumberOfGenericParams()
170+
}
171+
}

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

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -713,12 +713,34 @@ abstract class ImplOrTraitItemNode extends ItemNode {
713713
predicate hasAssocItem(string name) { name = this.getAnAssocItem().getName() }
714714
}
715715

716+
TypeItemNode resolveBuiltin(TypeRepr tr) {
717+
tr instanceof SliceTypeRepr and
718+
result instanceof Builtins::SliceType
719+
or
720+
tr instanceof ArrayTypeRepr and
721+
result instanceof Builtins::ArrayType
722+
or
723+
tr instanceof RefTypeRepr and
724+
result instanceof Builtins::RefType
725+
or
726+
tr instanceof PtrTypeRepr and
727+
result instanceof Builtins::PtrType
728+
or
729+
result.(Builtins::TupleType).getArity() = tr.(TupleTypeRepr).getNumberOfFields()
730+
}
731+
716732
final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
717733
Path getSelfPath() { result = super.getSelfTy().(PathTypeRepr).getPath() }
718734

719735
Path getTraitPath() { result = super.getTrait().(PathTypeRepr).getPath() }
720736

721-
TypeItemNode resolveSelfTy() { result = resolvePath(this.getSelfPath()) }
737+
TypeItemNode resolveSelfTyBuiltin() { result = resolveBuiltin(this.(Impl).getSelfTy()) }
738+
739+
TypeItemNode resolveSelfTy() {
740+
result = resolvePath(this.getSelfPath())
741+
or
742+
result = this.resolveSelfTyBuiltin()
743+
}
722744

723745
TraitItemNode resolveTraitTy() { result = resolvePath(this.getTraitPath()) }
724746

@@ -893,7 +915,11 @@ private class ModuleItemNode extends ModuleLikeNode instanceof Module {
893915
}
894916

895917
private class ImplItemNodeImpl extends ImplItemNode {
896-
TypeItemNode resolveSelfTyCand() { result = resolvePathCand(this.getSelfPath()) }
918+
TypeItemNode resolveSelfTyCand() {
919+
result = resolvePathCand(this.getSelfPath())
920+
or
921+
result = this.resolveSelfTyBuiltin()
922+
}
897923

898924
TraitItemNode resolveTraitTyCand() { result = resolvePathCand(this.getTraitPath()) }
899925
}
@@ -1764,6 +1790,9 @@ private ItemNode resolvePathCand0(RelevantPath path, Namespace ns) {
17641790
or
17651791
result = resolveUseTreeListItem(_, _, path, _) and
17661792
ns = result.getNamespace()
1793+
or
1794+
result = resolveBuiltin(path.getSegment().getTypeRepr()) and
1795+
ns.isType()
17671796
}
17681797

17691798
pragma[nomagic]
@@ -2141,7 +2170,9 @@ pragma[nomagic]
21412170
private predicate builtin(string name, ItemNode i) {
21422171
exists(BuiltinSourceFile builtins |
21432172
builtins.getFile().getBaseName() = "types.rs" and
2144-
i = builtins.getASuccessor(name)
2173+
i = builtins.getASuccessor(name) and
2174+
not name = ["Array", "Slice", "Ref", "Ptr"] and
2175+
not name.matches("Tuple%")
21452176
)
21462177
}
21472178

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

Lines changed: 62 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ private import codeql.rust.internal.CachedStages
77
private import codeql.rust.elements.internal.generated.Raw
88
private import codeql.rust.elements.internal.generated.Synth
99
private import codeql.rust.frameworks.stdlib.Stdlib
10+
private import codeql.rust.frameworks.stdlib.Builtins as Builtins
1011

1112
/**
1213
* Holds if a dyn trait type should have a type parameter associated with `n`. A
@@ -31,38 +32,20 @@ private predicate dynTraitTypeParameter(Trait trait, AstNode n) {
3132

3233
cached
3334
newtype TType =
34-
TTuple(int arity) {
35-
arity =
36-
[
37-
any(TupleTypeRepr t).getNumberOfFields(),
38-
any(TupleExpr e).getNumberOfFields(),
39-
any(TuplePat p).getNumberOfFields()
40-
] and
41-
Stages::TypeInferenceStage::ref()
42-
} or
43-
TStruct(Struct s) or
35+
TStruct(Struct s) { Stages::TypeInferenceStage::ref() } or
4436
TEnum(Enum e) or
4537
TTrait(Trait t) or
4638
TUnion(Union u) or
47-
TArrayType() or // todo: add size?
48-
TRefType() or // todo: add mut?
4939
TImplTraitType(ImplTraitTypeRepr impl) or
5040
TDynTraitType(Trait t) { t = any(DynTraitTypeRepr dt).getTrait() } or
51-
TSliceType() or
5241
TNeverType() or
53-
TPtrType() or
54-
TTupleTypeParameter(int arity, int i) { exists(TTuple(arity)) and i in [0 .. arity - 1] } or
5542
TTypeParamTypeParameter(TypeParam t) or
5643
TAssociatedTypeTypeParameter(TypeAlias t) { any(TraitItemNode trait).getAnAssocItem() = t } or
57-
TArrayTypeParameter() or
5844
TDynTraitTypeParameter(AstNode n) { dynTraitTypeParameter(_, n) } or
5945
TImplTraitTypeParameter(ImplTraitTypeRepr implTrait, TypeParam tp) {
6046
implTraitTypeParam(implTrait, _, tp)
6147
} or
62-
TRefTypeParameter() or
63-
TSelfTypeParameter(Trait t) or
64-
TSliceTypeParameter() or
65-
TPtrTypeParameter()
48+
TSelfTypeParameter(Trait t)
6649

6750
private predicate implTraitTypeParam(ImplTraitTypeRepr implTrait, int i, TypeParam tp) {
6851
implTrait.isInReturnPos() and
@@ -105,26 +88,25 @@ abstract class Type extends TType {
10588
}
10689

10790
/** A tuple type `(T, ...)`. */
108-
class TupleType extends Type, TTuple {
91+
class TupleType extends StructType {
10992
private int arity;
11093

111-
TupleType() { this = TTuple(arity) }
112-
113-
override TypeParameter getPositionalTypeParameter(int i) {
114-
result = TTupleTypeParameter(arity, i)
115-
}
94+
TupleType() { arity = this.getStruct().(Builtins::TupleType).getArity() }
11695

11796
/** Gets the arity of this tuple type. */
11897
int getArity() { result = arity }
11998

12099
override string toString() { result = "(T_" + arity + ")" }
100+
}
121101

122-
override Location getLocation() { result instanceof EmptyLocation }
102+
pragma[nomagic]
103+
TypeParamTypeParameter getTupleTypeParameter(int arity, int i) {
104+
result = any(TupleType t | t.getArity() = arity).getPositionalTypeParameter(i)
123105
}
124106

125107
/** The unit type `()`. */
126108
class UnitType extends TupleType {
127-
UnitType() { this = TTuple(0) }
109+
UnitType() { this.getArity() = 0 }
128110

129111
override string toString() { result = "()" }
130112
}
@@ -228,17 +210,15 @@ class UnionType extends Type, TUnion {
228210
* Array types like `[i64; 5]` are modeled as normal generic types
229211
* with a single type argument.
230212
*/
231-
class ArrayType extends Type, TArrayType {
232-
ArrayType() { this = TArrayType() }
213+
class ArrayType extends StructType {
214+
ArrayType() { this.getStruct() instanceof Builtins::ArrayType }
233215

234-
override TypeParameter getPositionalTypeParameter(int i) {
235-
result = TArrayTypeParameter() and
236-
i = 0
237-
}
238-
239-
override string toString() { result = "[]" }
216+
override string toString() { result = "[;]" }
217+
}
240218

241-
override Location getLocation() { result instanceof EmptyLocation }
219+
pragma[nomagic]
220+
TypeParamTypeParameter getArrayTypeParameter() {
221+
result = any(ArrayType t).getPositionalTypeParameter(0)
242222
}
243223

244224
/**
@@ -247,17 +227,15 @@ class ArrayType extends Type, TArrayType {
247227
* Reference types like `& i64` are modeled as normal generic types
248228
* with a single type argument.
249229
*/
250-
class RefType extends Type, TRefType {
251-
RefType() { this = TRefType() }
252-
253-
override TypeParameter getPositionalTypeParameter(int i) {
254-
result = TRefTypeParameter() and
255-
i = 0
256-
}
230+
class RefType extends StructType {
231+
RefType() { this.getStruct() instanceof Builtins::RefType }
257232

258233
override string toString() { result = "&" }
234+
}
259235

260-
override Location getLocation() { result instanceof EmptyLocation }
236+
pragma[nomagic]
237+
TypeParamTypeParameter getRefTypeParameter() {
238+
result = any(RefType t).getPositionalTypeParameter(0)
261239
}
262240

263241
/**
@@ -339,17 +317,15 @@ class ImplTraitReturnType extends ImplTraitType {
339317
* Slice types like `[i64]` are modeled as normal generic types
340318
* with a single type argument.
341319
*/
342-
class SliceType extends Type, TSliceType {
343-
SliceType() { this = TSliceType() }
344-
345-
override TypeParameter getPositionalTypeParameter(int i) {
346-
result = TSliceTypeParameter() and
347-
i = 0
348-
}
320+
class SliceType extends StructType {
321+
SliceType() { this.getStruct() instanceof Builtins::SliceType }
349322

350323
override string toString() { result = "[]" }
324+
}
351325

352-
override Location getLocation() { result instanceof EmptyLocation }
326+
pragma[nomagic]
327+
TypeParamTypeParameter getSliceTypeParameter() {
328+
result = any(SliceType t).getPositionalTypeParameter(0)
353329
}
354330

355331
class NeverType extends Type, TNeverType {
@@ -360,17 +336,19 @@ class NeverType extends Type, TNeverType {
360336
override Location getLocation() { result instanceof EmptyLocation }
361337
}
362338

363-
class PtrType extends Type, TPtrType {
364-
override TypeParameter getPositionalTypeParameter(int i) {
365-
i = 0 and
366-
result = TPtrTypeParameter()
367-
}
339+
class PtrType extends StructType {
340+
PtrType() { this.getStruct() instanceof Builtins::PtrType }
368341

369342
override string toString() { result = "*" }
370343

371344
override Location getLocation() { result instanceof EmptyLocation }
372345
}
373346

347+
pragma[nomagic]
348+
TypeParamTypeParameter getPtrTypeParameter() {
349+
result = any(PtrType t).getPositionalTypeParameter(0)
350+
}
351+
374352
/** A type parameter. */
375353
abstract class TypeParameter extends Type {
376354
override TypeParameter getPositionalTypeParameter(int i) { none() }
@@ -392,7 +370,32 @@ class TypeParamTypeParameter extends TypeParameter, TTypeParamTypeParameter {
392370

393371
TypeParam getTypeParam() { result = typeParam }
394372

395-
override string toString() { result = typeParam.toString() }
373+
override string toString() {
374+
this = any(SliceType st).getATypeParameter() and
375+
result = "[T]"
376+
or
377+
this = any(ArrayType at).getATypeParameter() and
378+
result = "[T;...]"
379+
or
380+
this = any(RefType rt).getATypeParameter() and
381+
result = "&T"
382+
or
383+
this = any(PtrType pt).getATypeParameter() and
384+
result = "*T"
385+
or
386+
exists(TupleType tt, int arity, int i |
387+
this = tt.getPositionalTypeParameter(i) and
388+
arity = tt.getArity() and
389+
result = i + "(" + arity + ")"
390+
)
391+
or
392+
not this = any(SliceType st).getATypeParameter() and
393+
not this = any(ArrayType at).getATypeParameter() and
394+
not this = any(RefType rt).getATypeParameter() and
395+
not this = any(PtrType pt).getATypeParameter() and
396+
not this = any(TupleType tt).getATypeParameter() and
397+
result = typeParam.toString()
398+
}
396399

397400
override Location getLocation() { result = typeParam.getLocation() }
398401
}
@@ -430,37 +433,6 @@ class AssociatedTypeTypeParameter extends TypeParameter, TAssociatedTypeTypePara
430433
override Location getLocation() { result = typeAlias.getLocation() }
431434
}
432435

433-
/**
434-
* A tuple type parameter. For instance the `T` in `(T, U)`.
435-
*
436-
* Since tuples are structural their type parameters can be represented as their
437-
* positional index. The type inference library requires that type parameters
438-
* belong to a single type, so we also include the arity of the tuple type.
439-
*/
440-
class TupleTypeParameter extends TypeParameter, TTupleTypeParameter {
441-
private int arity;
442-
private int index;
443-
444-
TupleTypeParameter() { this = TTupleTypeParameter(arity, index) }
445-
446-
override string toString() { result = index.toString() + "(" + arity + ")" }
447-
448-
override Location getLocation() { result instanceof EmptyLocation }
449-
450-
/** Gets the index of this tuple type parameter. */
451-
int getIndex() { result = index }
452-
453-
/** Gets the tuple type that corresponds to this tuple type parameter. */
454-
TupleType getTupleType() { result = TTuple(arity) }
455-
}
456-
457-
/** An implicit array type parameter. */
458-
class ArrayTypeParameter extends TypeParameter, TArrayTypeParameter {
459-
override string toString() { result = "[T;...]" }
460-
461-
override Location getLocation() { result instanceof EmptyLocation }
462-
}
463-
464436
class DynTraitTypeParameter extends TypeParameter, TDynTraitTypeParameter {
465437
private AstNode n;
466438

@@ -508,26 +480,6 @@ class ImplTraitTypeParameter extends TypeParameter, TImplTraitTypeParameter {
508480
override Location getLocation() { result = typeParam.getLocation() }
509481
}
510482

511-
/** An implicit reference type parameter. */
512-
class RefTypeParameter extends TypeParameter, TRefTypeParameter {
513-
override string toString() { result = "&T" }
514-
515-
override Location getLocation() { result instanceof EmptyLocation }
516-
}
517-
518-
/** An implicit slice type parameter. */
519-
class SliceTypeParameter extends TypeParameter, TSliceTypeParameter {
520-
override string toString() { result = "[T]" }
521-
522-
override Location getLocation() { result instanceof EmptyLocation }
523-
}
524-
525-
class PtrTypeParameter extends TypeParameter, TPtrTypeParameter {
526-
override string toString() { result = "*T" }
527-
528-
override Location getLocation() { result instanceof EmptyLocation }
529-
}
530-
531483
/**
532484
* The implicit `Self` type parameter of a trait, that refers to the
533485
* implementing type of the trait.

0 commit comments

Comments
 (0)