Skip to content

Commit 3c24886

Browse files
committed
wip
1 parent eb435c7 commit 3c24886

4 files changed

Lines changed: 786 additions & 99 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: 40 additions & 77 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+
isUnitBlockExpr(e)
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,13 @@ 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-
20312014
/**
20322015
* Gets the root type of the range expression `re`.
20332016
*/
20342017
pragma[nomagic]
2035-
private Type inferRangeExprType(RangeExpr re) { result = TDataType(getRangeType(re)) }
2018+
private Type inferRangeFullExprType(RangeFullExpr re) {
2019+
exists(re) and result = TDataType(any(RangeFullStruct t))
2020+
}
20362021

20372022
/**
20382023
* A matching configuration for resolving types of deconstruction patterns like
@@ -2144,15 +2129,6 @@ private Type inferForLoopExprType(AstNode n, TypePath path) {
21442129
)
21452130
}
21462131

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-
21562132
/** Holds if `n` is implicitly dereferenced and/or borrowed. */
21572133
cached
21582134
predicate implicitDerefChainBorrow(Expr e, DerefChain derefChain, boolean borrow) {
@@ -2943,30 +2919,6 @@ private module Input3 implements InputSig3 {
29432919
exists(c)
29442920
}
29452921

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-
29702922
pragma[nomagic]
29712923
private Type inferClosureArgsType(ClosureExpr ce, TypePath path) {
29722924
path = TypePath::singleton(TDynTraitTypeParameter(_, any(FnTrait t).getTypeParam())) and
@@ -2980,27 +2932,17 @@ private module Input3 implements InputSig3 {
29802932
result = inferRefPatType(n) and
29812933
path.isEmpty()
29822934
or
2983-
result = inferRefExprType(n) and
2984-
path.isEmpty()
2985-
or
29862935
result = inferStructExprType(n, path)
29872936
or
29882937
result = inferStructPatType(n, path)
29892938
or
2990-
result = inferAssignmentOperationType(n, path)
2991-
or
2992-
result = inferRangeExprType(n) and
2939+
result = inferRangeFullExprType(n) and
29932940
path.isEmpty()
29942941
or
29952942
result = inferTupleRootType(n) and
29962943
path.isEmpty()
29972944
or
2998-
result = inferBlockExprType(n, path)
2999-
or
3000-
result = inferArrayExprType(n) and
3001-
path.isEmpty()
3002-
or
3003-
result = inferArgList(n, path)
2945+
result = inferAsyncUnitBlockExprType(n, path)
30042946
or
30052947
exprHasUnitType(n) and
30062948
path.isEmpty() and
@@ -3064,6 +3006,15 @@ private module Input3 implements InputSig3 {
30643006
or
30653007
n1 = n2.(MacroPat).getMacroCall().getMacroCallExpansion()
30663008
)
3009+
or
3010+
// Rust closure types like `Fn<(A, B) -> C>` are syntactic sugar for `Fn<Args = (A, B), Output = C>`,
3011+
// so in calls to a closure, we consider the entire argument list as a single tuple argument.
3012+
exists(CallExprImpl::DynamicCallExpr dce, TupleType tt, int i |
3013+
n1 = dce.getSyntacticPositionalArgument(i) and
3014+
n2 = dce.getArgList() and
3015+
tt.getArity() = dce.getNumberOfSyntacticArguments() and
3016+
prefix2 = TypePath::singleton(tt.getPositionalTypeParameter(i))
3017+
)
30673018
)
30683019
or
30693020
n1 =
@@ -3099,6 +3050,18 @@ private module Input3 implements InputSig3 {
30993050
or
31003051
e instanceof OptionEnum
31013052
)
3053+
or
3054+
n1 =
3055+
any(IdentPat ip |
3056+
n2 = ip.getName() and
3057+
prefix1.isEmpty() and
3058+
if ip.isRef()
3059+
then
3060+
exists(boolean isMutable | if ip.isMut() then isMutable = true else isMutable = false |
3061+
prefix2 = TypePath::singleton(getRefTypeParameter(isMutable))
3062+
)
3063+
else prefix2.isEmpty()
3064+
)
31023065
}
31033066

31043067
pragma[nomagic]

0 commit comments

Comments
 (0)