Skip to content

Commit 3f05f50

Browse files
committed
wip
1 parent eb435c7 commit 3f05f50

4 files changed

Lines changed: 802 additions & 135 deletions

File tree

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
private import rust
44
private import codeql.rust.internal.PathResolution
55
private import TypeMention
6-
private import TypeInference
76
private import codeql.rust.internal.CachedStages
87
private import codeql.rust.elements.internal.generated.Raw
98
private import codeql.rust.elements.internal.generated.Synth

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

Lines changed: 64 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -276,12 +276,6 @@ private Type inferStructPatType(StructPat sp, TypePath path) {
276276
result = sp.getPath().(TypeMention).getTypeAt(path)
277277
}
278278

279-
private Type inferAssignmentOperationType(AstNode n, TypePath path) {
280-
n instanceof AssignmentOperation and
281-
path.isEmpty() and
282-
result instanceof UnitType
283-
}
284-
285279
pragma[nomagic]
286280
private Struct getRangeType(RangeExpr re) {
287281
re instanceof RangeFromExpr and
@@ -290,9 +284,6 @@ private Struct getRangeType(RangeExpr re) {
290284
re instanceof RangeToExpr and
291285
result instanceof RangeToStruct
292286
or
293-
re instanceof RangeFullExpr and
294-
result instanceof RangeFullStruct
295-
or
296287
re instanceof RangeFromToExpr and
297288
result instanceof RangeStruct
298289
or
@@ -1972,30 +1963,28 @@ predicate isUnitBlockExpr(BlockExpr be) {
19721963
}
19731964

19741965
pragma[nomagic]
1975-
private Type inferBlockExprType(BlockExpr be, TypePath path) {
1976-
// `typeEquality` handles the non-root case
1977-
if be instanceof AsyncBlockExpr
1978-
then (
1979-
path.isEmpty() and
1980-
result = getFutureTraitType()
1981-
or
1982-
isUnitBlockExpr(be) and
1983-
path = TypePath::singleton(getDynFutureOutputTypeParameter()) and
1984-
result instanceof UnitType
1985-
) else (
1986-
isUnitBlockExpr(be) and
1987-
path.isEmpty() and
1988-
result instanceof UnitType
1989-
)
1966+
private Type inferAsyncUnitBlockExprType(AsyncBlockExpr be, TypePath path) {
1967+
isUnitBlockExpr(be) and
1968+
path = TypePath::singleton(getDynFutureOutputTypeParameter()) and
1969+
result instanceof UnitType
19901970
}
19911971

19921972
pragma[nomagic]
1993-
private predicate exprHasUnitType(Expr e) {
1973+
private predicate exprHasUnitType(AstNode e) {
19941974
e = any(IfExpr ie | not ie.hasElse())
19951975
or
19961976
e instanceof WhileExpr
19971977
or
19981978
e instanceof ForExpr
1979+
or
1980+
e instanceof AssignmentOperation
1981+
or
1982+
e = any(BlockExpr be | isUnitBlockExpr(be) and not be.isAsync())
1983+
or
1984+
exists(CallExprImpl::DynamicCallExpr dce |
1985+
e = dce.getArgList() and
1986+
dce.getNumberOfSyntacticArguments() = 0
1987+
)
19991988
}
20001989

20011990
final private class AwaitTarget extends Expr {
@@ -2022,17 +2011,10 @@ private Type inferAwaitExprType(AstNode n, TypePath path) {
20222011
)
20232012
}
20242013

2025-
/**
2026-
* Gets the root type of the array expression `ae`.
2027-
*/
2028-
pragma[nomagic]
2029-
private Type inferArrayExprType(ArrayExpr ae) { exists(ae) and result instanceof ArrayType }
2030-
2031-
/**
2032-
* Gets the root type of the range expression `re`.
2033-
*/
20342014
pragma[nomagic]
2035-
private Type inferRangeExprType(RangeExpr re) { result = TDataType(getRangeType(re)) }
2015+
private Type inferRangeFullExprType(RangeFullExpr re) {
2016+
exists(re) and result = TDataType(any(RangeFullStruct t))
2017+
}
20362018

20372019
/**
20382020
* A matching configuration for resolving types of deconstruction patterns like
@@ -2144,15 +2126,6 @@ private Type inferForLoopExprType(AstNode n, TypePath path) {
21442126
)
21452127
}
21462128

2147-
pragma[nomagic]
2148-
private TupleType inferArgList(ArgList args, TypePath path) {
2149-
exists(CallExprImpl::DynamicCallExpr dce |
2150-
args = dce.getArgList() and
2151-
result.getArity() = dce.getNumberOfSyntacticArguments() and
2152-
path.isEmpty()
2153-
)
2154-
}
2155-
21562129
/** Holds if `n` is implicitly dereferenced and/or borrowed. */
21572130
cached
21582131
predicate implicitDerefChainBorrow(Expr e, DerefChain derefChain, boolean borrow) {
@@ -2943,72 +2916,12 @@ private module Input3 implements InputSig3 {
29432916
exists(c)
29442917
}
29452918

2946-
predicate stepCertainLanguageSpecific(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) {
2947-
n1 =
2948-
any(IdentPat ip |
2949-
n2 = ip.getName() and
2950-
prefix1.isEmpty() and
2951-
if ip.isRef()
2952-
then
2953-
exists(boolean isMutable | if ip.isMut() then isMutable = true else isMutable = false |
2954-
prefix2 = TypePath::singleton(getRefTypeParameter(isMutable))
2955-
)
2956-
else prefix2.isEmpty()
2957-
)
2958-
or
2959-
// Rust closure types like `Fn<(A, B) -> C>` are syntactic sugar for `Fn<Args = (A, B), Output = C>`,
2960-
// so in calls to a closure, we consider the entire argument list as a single tuple argument.
2961-
exists(CallExprImpl::DynamicCallExpr dce, TupleType tt, int i |
2962-
n1 = dce.getSyntacticPositionalArgument(i) and
2963-
n2 = dce.getArgList() and
2964-
tt.getArity() = dce.getNumberOfSyntacticArguments() and
2965-
prefix1.isEmpty() and
2966-
prefix2 = TypePath::singleton(tt.getPositionalTypeParameter(i))
2967-
)
2968-
}
2969-
29702919
pragma[nomagic]
29712920
private Type inferClosureArgsType(ClosureExpr ce, TypePath path) {
29722921
path = TypePath::singleton(TDynTraitTypeParameter(_, any(FnTrait t).getTypeParam())) and
29732922
result.(TupleType).getArity() = ce.getNumberOfParams()
29742923
}
29752924

2976-
pragma[nomagic]
2977-
Type inferTypeCertainLanguageSpecific(AstNode n, TypePath path) {
2978-
result = inferLiteralType(n, path, true)
2979-
or
2980-
result = inferRefPatType(n) and
2981-
path.isEmpty()
2982-
or
2983-
result = inferRefExprType(n) and
2984-
path.isEmpty()
2985-
or
2986-
result = inferStructExprType(n, path)
2987-
or
2988-
result = inferStructPatType(n, path)
2989-
or
2990-
result = inferAssignmentOperationType(n, path)
2991-
or
2992-
result = inferRangeExprType(n) and
2993-
path.isEmpty()
2994-
or
2995-
result = inferTupleRootType(n) and
2996-
path.isEmpty()
2997-
or
2998-
result = inferBlockExprType(n, path)
2999-
or
3000-
result = inferArrayExprType(n) and
3001-
path.isEmpty()
3002-
or
3003-
result = inferArgList(n, path)
3004-
or
3005-
exprHasUnitType(n) and
3006-
path.isEmpty() and
3007-
result instanceof UnitType
3008-
or
3009-
result = inferClosureArgsType(n, path)
3010-
}
3011-
30122925
predicate stepLanguageSpecific(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) {
30132926
// When `n2` is `*n1` propagate type information from a raw pointer type
30142927
// parameter at `n1` (all other deref expressions are handled as calls)
@@ -3064,6 +2977,15 @@ private module Input3 implements InputSig3 {
30642977
or
30652978
n1 = n2.(MacroPat).getMacroCall().getMacroCallExpansion()
30662979
)
2980+
or
2981+
// Rust closure types like `Fn<(A, B) -> C>` are syntactic sugar for `Fn<Args = (A, B), Output = C>`,
2982+
// so in calls to a closure, we consider the entire argument list as a single tuple argument.
2983+
exists(CallExprImpl::DynamicCallExpr dce, TupleType tt, int i |
2984+
n1 = dce.getSyntacticPositionalArgument(i) and
2985+
n2 = dce.getArgList() and
2986+
tt.getArity() = dce.getNumberOfSyntacticArguments() and
2987+
prefix2 = TypePath::singleton(tt.getPositionalTypeParameter(i))
2988+
)
30672989
)
30682990
or
30692991
n1 =
@@ -3099,6 +3021,18 @@ private module Input3 implements InputSig3 {
30993021
or
31003022
e instanceof OptionEnum
31013023
)
3024+
or
3025+
n1 =
3026+
any(IdentPat ip |
3027+
n2 = ip.getName() and
3028+
prefix1.isEmpty() and
3029+
if ip.isRef()
3030+
then
3031+
exists(boolean isMutable | if ip.isMut() then isMutable = true else isMutable = false |
3032+
prefix2 = TypePath::singleton(getRefTypeParameter(isMutable))
3033+
)
3034+
else prefix2.isEmpty()
3035+
)
31023036
}
31033037

31043038
pragma[nomagic]
@@ -3124,6 +3058,32 @@ private module Input3 implements InputSig3 {
31243058
or
31253059
result = inferUnknownType(n, path)
31263060
}
3061+
3062+
pragma[nomagic]
3063+
Type inferTypeCertainLanguageSpecific(AstNode n, TypePath path) {
3064+
result = inferLiteralType(n, path, true)
3065+
or
3066+
result = inferRefPatType(n) and
3067+
path.isEmpty()
3068+
or
3069+
result = inferStructExprType(n, path)
3070+
or
3071+
result = inferStructPatType(n, path)
3072+
or
3073+
result = inferRangeFullExprType(n) and
3074+
path.isEmpty()
3075+
or
3076+
result = inferTupleRootType(n) and
3077+
path.isEmpty()
3078+
or
3079+
result = inferAsyncUnitBlockExprType(n, path)
3080+
or
3081+
exprHasUnitType(n) and
3082+
path.isEmpty() and
3083+
result instanceof UnitType
3084+
or
3085+
result = inferClosureArgsType(n, path)
3086+
}
31273087
}
31283088

31293089
private module M3 = Make3<Input3>;

0 commit comments

Comments
 (0)