Skip to content

Commit 241efea

Browse files
committed
Rust: Type inference 2.0
1 parent c5b7485 commit 241efea

18 files changed

Lines changed: 1377 additions & 3451 deletions

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

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import rust
3030
* The `backref` predicate starts with `1 = 1 or` to ensure that the predicate will be optimized down to a constant by the optimizer.
3131
*/
3232
module Stages {
33+
private import codeql.rust.internal.typeinference.TypeInference as TypeInference
34+
3335
/**
3436
* The abstract syntex tree (AST) stage.
3537
*/
@@ -126,32 +128,7 @@ module Stages {
126128
/**
127129
* The type inference stage.
128130
*/
129-
cached
130-
module TypeInferenceStage {
131-
private import codeql.rust.internal.typeinference.Type
132-
private import codeql.rust.internal.typeinference.TypeInference
133-
134-
/**
135-
* Always holds.
136-
* Ensures that a predicate is evaluated as part of the type inference stage.
137-
*/
138-
cached
139-
predicate ref() { 1 = 1 }
140-
141-
/**
142-
* DO NOT USE!
143-
*
144-
* Contains references to each predicate that use the above `ref` predicate.
145-
*/
146-
cached
147-
predicate backref() {
148-
1 = 1
149-
or
150-
exists(Type t)
151-
or
152-
exists(inferType(_))
153-
}
154-
}
131+
module TypeInferenceStage = TypeInference::CachedStage;
155132

156133
/**
157134
* The data flow stage.

rust/ql/lib/codeql/rust/internal/typeinference/BlanketImplementation.qll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,7 @@ module SatisfiesBlanketConstraint<
9696

9797
Type getTypeAt(TypePath path) {
9898
result = at.getTypeAt(blanketPath.appendInverse(path)) and
99-
not result = TNeverType() and
100-
not result = TUnknownType()
99+
not result instanceof PseudoType
101100
}
102101

103102
string toString() { result = at.toString() + " [blanket at " + blanketPath.toString() + "]" }

rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,7 @@ module ArgIsInstantiationOf<ArgSig Arg, IsInstantiationOfInputSig<Arg, AssocFunc
329329
private class ArgSubst extends ArgFinal {
330330
Type getTypeAt(TypePath path) {
331331
result = substituteLookupTraits0(this.getEnclosingItemNode(), super.getTypeAt(path)) and
332-
not result = TNeverType() and
333-
not result = TUnknownType()
332+
not result instanceof PseudoType
334333
}
335334
}
336335

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

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
private import rust
44
private import codeql.rust.internal.PathResolution
55
private import TypeMention
6+
private import TypeInference
67
private import codeql.rust.internal.CachedStages
78
private import codeql.rust.elements.internal.generated.Raw
89
private import codeql.rust.elements.internal.generated.Synth
@@ -36,8 +37,13 @@ newtype TType =
3637
TTrait(Trait t) or
3738
TImplTraitType(ImplTraitTypeRepr impl) or
3839
TDynTraitType(Trait t) { t = any(DynTraitTypeRepr dt).getTrait() } or
39-
TNeverType() or
4040
TUnknownType() or
41+
TClosureParameterPseudoType(Param p) {
42+
exists(ClosureExpr ce |
43+
p = ce.getParam(_) and
44+
not p.hasTypeRepr()
45+
)
46+
} or
4147
TTypeParamTypeParameter(TypeParam t) or
4248
TAssociatedTypeTypeParameter(Trait trait, AssocType typeAlias) {
4349
getTraitAssocType(trait) = typeAlias
@@ -326,14 +332,6 @@ TypeParamTypeParameter getSliceTypeParameter() {
326332
result = any(SliceType t).getPositionalTypeParameter(0)
327333
}
328334

329-
class NeverType extends Type, TNeverType {
330-
override TypeParameter getPositionalTypeParameter(int i) { none() }
331-
332-
override string toString() { result = "!" }
333-
334-
override Location getLocation() { result instanceof EmptyLocation }
335-
}
336-
337335
abstract class PtrType extends StructType { }
338336

339337
pragma[nomagic]
@@ -355,6 +353,10 @@ class PtrConstType extends PtrType {
355353
override string toString() { result = "*const" }
356354
}
357355

356+
abstract class PseudoType extends Type {
357+
override TypeParameter getPositionalTypeParameter(int i) { none() }
358+
}
359+
358360
/**
359361
* A special pseudo type used to indicate that the actual type may have to be
360362
* inferred by propagating type information back into call arguments.
@@ -377,14 +379,24 @@ class PtrConstType extends PtrType {
377379
* into call arguments (including method call receivers), in order to avoid
378380
* combinatorial explosions.
379381
*/
380-
class UnknownType extends Type, TUnknownType {
381-
override TypeParameter getPositionalTypeParameter(int i) { none() }
382-
383-
override string toString() { result = "(context typed)" }
382+
class UnknownType extends PseudoType, TUnknownType {
383+
override string toString() { result = "(unknown type)" }
384384

385385
override Location getLocation() { result instanceof EmptyLocation }
386386
}
387387

388+
class ClosureParameterPseudoType extends PseudoType, TClosureParameterPseudoType {
389+
private Param param;
390+
391+
ClosureParameterPseudoType() { this = TClosureParameterPseudoType(param) }
392+
393+
Param getParam() { result = param }
394+
395+
override string toString() { result = "(closure parameter " + param + ")" }
396+
397+
override Location getLocation() { result = param.getLocation() }
398+
}
399+
388400
/** A type parameter. */
389401
abstract class TypeParameter extends Type {
390402
override TypeParameter getPositionalTypeParameter(int i) { none() }

0 commit comments

Comments
 (0)