Skip to content

Commit ec6c301

Browse files
committed
Rust: Type inference performance improvements
1 parent 793d2c7 commit ec6c301

File tree

4 files changed

+44
-25
lines changed

4 files changed

+44
-25
lines changed

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

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ predicate traitTypeParameterOccurrence(
101101
* order to determine whether it is the correct resolution.
102102
*/
103103
pragma[nomagic]
104-
predicate functionResolutionDependsOnArgument(
104+
private predicate functionResolutionDependsOnArgument0(
105105
ImplItemNode impl, Function f, FunctionPosition pos, TypePath path, Type type
106106
) {
107107
/*
@@ -133,7 +133,30 @@ predicate functionResolutionDependsOnArgument(
133133
implHasSibling(impl, trait) and
134134
traitTypeParameterOccurrence(trait, _, functionName, pos, path, _) and
135135
type = getAssocFunctionTypeAt(f, impl, pos, path) and
136-
f = impl.getASuccessor(functionName) and
136+
f = impl.getASuccessor(functionName)
137+
)
138+
}
139+
140+
/**
141+
* Holds if resolving the function `f` in `impl` with the name `functionName`
142+
* requires inspecting the type of applied _arguments_ at position `pos` in
143+
* order to determine whether it is the correct resolution.
144+
*/
145+
pragma[nomagic]
146+
predicate functionResolutionDependsOnArgument(
147+
ImplItemNode impl, Function f, FunctionPosition pos, TypePath path, Type type
148+
) {
149+
functionResolutionDependsOnArgument0(impl, f, pos, path, type) and
150+
(
137151
pos.isPosition()
152+
or
153+
pos.isReturn() and
154+
forall(FunctionPosition pos0, TypePath path0, Type type0 |
155+
pos0.isPosition() and
156+
functionResolutionDependsOnArgument0(impl, f, pos0, path0, type0)
157+
|
158+
path0.isEmpty() and
159+
type0.(TypeParamTypeParameter).getTypeParam() = any(TypeParam tp | not tp.hasTypeBound())
160+
)
138161
)
139162
}

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

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,9 +1159,6 @@ private module ContextTyping {
11591159
inferType(n, path) = TUnknownType()
11601160
}
11611161

1162-
pragma[nomagic]
1163-
private predicate hasUnknownType(AstNode n) { hasUnknownTypeAt(n, _) }
1164-
11651162
signature Type inferCallTypeSig(AstNode n, boolean isReturn, TypePath path);
11661163

11671164
/**
@@ -1172,24 +1169,21 @@ private module ContextTyping {
11721169
*/
11731170
module CheckContextTyping<inferCallTypeSig/3 inferCallType> {
11741171
pragma[nomagic]
1175-
private Type inferCallTypeFromContextCand(AstNode n, TypePath path, TypePath prefix) {
1176-
result = inferCallType(n, false, path) and
1177-
hasUnknownType(n) and
1178-
prefix = path
1179-
or
1180-
exists(TypePath mid |
1181-
result = inferCallTypeFromContextCand(n, path, mid) and
1182-
mid.isSnoc(prefix, _)
1183-
)
1184-
}
1172+
Type inferCallNonReturnType(AstNode n, TypePath path) { result = inferCallType(n, false, path) }
11851173

11861174
pragma[nomagic]
11871175
Type check(AstNode n, TypePath path) {
11881176
result = inferCallType(n, true, path)
11891177
or
1190-
exists(TypePath prefix |
1191-
result = inferCallTypeFromContextCand(n, path, prefix) and
1192-
hasUnknownTypeAt(n, prefix)
1178+
exists(Type t, TypePath path0 |
1179+
t = inferCallNonReturnType(n, path0) and
1180+
hasUnknownTypeAt(n, path0)
1181+
|
1182+
result = t and
1183+
path = path0
1184+
or
1185+
result = TUnknownType() and
1186+
path = path0.append(TypePath::singleton(t.getATypeParameter()))
11931187
)
11941188
}
11951189
}
@@ -2669,9 +2663,8 @@ private module NonMethodResolution {
26692663
then
26702664
// We only check that the context of the call provides relevant type information
26712665
// when no argument can
2672-
not exists(FunctionPosition pos0 |
2673-
FunctionOverloading::traitTypeParameterOccurrence(trait, traitFunction, _, pos0, _, _) and
2674-
not pos0.isReturn()
2666+
not exists(FunctionPosition pos0 | not pos0.isReturn() |
2667+
FunctionOverloading::traitTypeParameterOccurrence(trait, traitFunction, _, pos0, _, _)
26752668
or
26762669
FunctionOverloading::functionResolutionDependsOnArgument(impl, implFunction, pos0, _, _)
26772670
)
@@ -2837,7 +2830,7 @@ private module NonMethodResolution {
28372830
NonMethodFunction resolveTraitFunctionViaPathResolution(TraitItemNode trait) {
28382831
this.hasTrait() and
28392832
result = this.getPathResolutionResolved() and
2840-
result = trait.getASuccessor(_)
2833+
result = trait.getAnAssocItem()
28412834
}
28422835
}
28432836

rust/ql/test/query-tests/security/CWE-312/CONSISTENCY/PathResolutionConsistency.expected

Lines changed: 0 additions & 2 deletions
This file was deleted.

shared/typeinference/codeql/typeinference/internal/TypeInference.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,11 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
980980
not t = abs.getATypeParameter()
981981
}
982982

983+
pragma[nomagic]
984+
private predicate hasTypeConstraint(HasTypeTree term, Type constraint) {
985+
hasTypeConstraint(term, constraint, constraint)
986+
}
987+
983988
/**
984989
* Holds if the type tree at `tt` satisfies the constraint `constraint`
985990
* with the type `t` at `path`.
@@ -994,7 +999,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
994999
path = prefix0.append(suffix)
9951000
)
9961001
or
997-
hasTypeConstraint(tt, constraint, constraint) and
1002+
hasTypeConstraint(tt, constraint) and
9981003
t = getTypeAt(tt, path)
9991004
}
10001005

0 commit comments

Comments
 (0)