Skip to content

Commit 52aa7e3

Browse files
authored
Merge pull request #19624 from paldepind/type-inference-experiment
Rust: Refactor type equality
2 parents 8b9e5b4 + 08277e4 commit 52aa7e3

File tree

1 file changed

+43
-66
lines changed

1 file changed

+43
-66
lines changed

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

Lines changed: 43 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -207,81 +207,58 @@ private Type inferAssignmentOperationType(AstNode n, TypePath path) {
207207
}
208208

209209
/**
210-
* Holds if the type of `n1` at `path1` is the same as the type of `n2` at
211-
* `path2` and type information should propagate in both directions through the
212-
* type equality.
210+
* Holds if the type tree of `n1` at `prefix1` should be equal to the type tree
211+
* of `n2` at `prefix2` and type information should propagate in both directions
212+
* through the type equality.
213213
*/
214-
bindingset[path1]
215-
bindingset[path2]
216-
private predicate typeEquality(AstNode n1, TypePath path1, AstNode n2, TypePath path2) {
217-
exists(Variable v |
218-
path1 = path2 and
219-
n1 = v.getAnAccess()
220-
|
221-
n2 = v.getPat()
214+
private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) {
215+
prefix1.isEmpty() and
216+
prefix2.isEmpty() and
217+
(
218+
exists(Variable v | n1 = v.getAnAccess() |
219+
n2 = v.getPat()
220+
or
221+
n2 = v.getParameter().(SelfParam)
222+
)
222223
or
223-
n2 = v.getParameter().(SelfParam)
224-
)
225-
or
226-
exists(LetStmt let |
227-
let.getPat() = n1 and
228-
let.getInitializer() = n2 and
229-
path1 = path2
230-
)
231-
or
232-
n1 = n2.(ParenExpr).getExpr() and
233-
path1 = path2
234-
or
235-
n1 = n2.(BlockExpr).getStmtList().getTailExpr() and
236-
path1 = path2
237-
or
238-
n1 = n2.(IfExpr).getABranch() and
239-
path1 = path2
240-
or
241-
n1 = n2.(MatchExpr).getAnArm().getExpr() and
242-
path1 = path2
243-
or
244-
exists(BreakExpr break |
245-
break.getExpr() = n1 and
246-
break.getTarget() = n2.(LoopExpr) and
247-
path1 = path2
248-
)
249-
or
250-
exists(AssignmentExpr be |
251-
n1 = be.getLhs() and
252-
n2 = be.getRhs() and
253-
path1 = path2
254-
)
255-
}
256-
257-
bindingset[path1]
258-
private predicate typeEqualityLeft(AstNode n1, TypePath path1, AstNode n2, TypePath path2) {
259-
typeEquality(n1, path1, n2, path2)
260-
or
261-
n2 =
262-
any(DerefExpr pe |
263-
pe.getExpr() = n1 and
264-
path1.isCons(TRefTypeParameter(), path2)
224+
exists(LetStmt let |
225+
let.getPat() = n1 and
226+
let.getInitializer() = n2
265227
)
266-
}
267-
268-
bindingset[path2]
269-
private predicate typeEqualityRight(AstNode n1, TypePath path1, AstNode n2, TypePath path2) {
270-
typeEquality(n1, path1, n2, path2)
271-
or
272-
n2 =
273-
any(DerefExpr pe |
274-
pe.getExpr() = n1 and
275-
path1 = TypePath::cons(TRefTypeParameter(), path2)
228+
or
229+
n1 = n2.(ParenExpr).getExpr()
230+
or
231+
n1 = n2.(BlockExpr).getStmtList().getTailExpr()
232+
or
233+
n1 = n2.(IfExpr).getABranch()
234+
or
235+
n1 = n2.(MatchExpr).getAnArm().getExpr()
236+
or
237+
exists(BreakExpr break |
238+
break.getExpr() = n1 and
239+
break.getTarget() = n2.(LoopExpr)
240+
)
241+
or
242+
exists(AssignmentExpr be |
243+
n1 = be.getLhs() and
244+
n2 = be.getRhs()
276245
)
246+
)
247+
or
248+
n1 = n2.(DerefExpr).getExpr() and
249+
prefix1 = TypePath::singleton(TRefTypeParameter()) and
250+
prefix2.isEmpty()
277251
}
278252

279253
pragma[nomagic]
280254
private Type inferTypeEquality(AstNode n, TypePath path) {
281-
exists(AstNode n2, TypePath path2 | result = inferType(n2, path2) |
282-
typeEqualityRight(n, path, n2, path2)
255+
exists(TypePath prefix1, AstNode n2, TypePath prefix2, TypePath suffix |
256+
result = inferType(n2, prefix2.appendInverse(suffix)) and
257+
path = prefix1.append(suffix)
258+
|
259+
typeEquality(n, prefix1, n2, prefix2)
283260
or
284-
typeEqualityLeft(n2, path2, n, path)
261+
typeEquality(n2, prefix2, n, prefix1)
285262
)
286263
}
287264

0 commit comments

Comments
 (0)