Unified: Type inference first version - #22639
Conversation
| private import TypeMention | ||
| private import TypeInference | ||
| private import TypeInference::Consistency as Consistency | ||
| import TypeInference::Consistency |
9adf294 to
bbc8b9a
Compare
e71b6f6 to
5886197
Compare
| * parameter. | ||
| */ | ||
| bindingset[t, arity, i] | ||
| abstract predicate functionInvokeSignature(Type t, int arity, int i, int j, TypePath path); |
5886197 to
b2b2531
Compare
ab9a603 to
76692f4
Compare
76692f4 to
c5db7b1
Compare
fe9c6eb to
ebbac0e
Compare
| } | ||
|
|
||
| /** Provides predicates for debugging the type inference implementation. */ | ||
| private module Debug { |
| /** Provides predicates for debugging the type inference implementation. */ | ||
| private module Debug { | ||
| AstNode getRelevantNode() { | ||
| exists(string filepath, int startline, int startcolumn, int endline, int endcolumn | |
| /** Provides predicates for debugging the type inference implementation. */ | ||
| private module Debug { | ||
| AstNode getRelevantNode() { | ||
| exists(string filepath, int startline, int startcolumn, int endline, int endcolumn | |
| /** Provides predicates for debugging the type inference implementation. */ | ||
| private module Debug { | ||
| AstNode getRelevantNode() { | ||
| exists(string filepath, int startline, int startcolumn, int endline, int endcolumn | |
ebbac0e to
228fe9c
Compare
228fe9c to
a159ea5
Compare
e58e192 to
8d76018
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Four unresolved moderate issues can produce incorrect inferred types, call targets, and dataflow edges.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 1
Open (1)
What changed in this PR
Introduces initial Swift type inference for the unified CodeQL library and integrates inferred call targets with dataflow.
Changes:
- Adds type representations, inference plugins, built-in models, and consistency checks.
- Supports generics, tuples, closures, protocols, aliases, fields, and call resolution.
- Adds extensive inference and dataflow tests.
| File | Review |
|---|---|
unified/tools/builtins/types.swift |
Adds modeled built-in operations. |
unified/ql/test/library-tests/type-inference/type-inference.qlref |
Registers inference tests and postprocessing. |
unified/ql/test/library-tests/type-inference/type-inference.ql |
Defines inference and resolution assertions. |
unified/ql/test/library-tests/type-inference/type_constraints.swift |
Tests generic constraints. |
unified/ql/test/library-tests/type-inference/type_alias.swift |
Tests generic type aliases. |
unified/ql/test/library-tests/type-inference/tuples.swift |
Tests tuple inference. |
unified/ql/test/library-tests/type-inference/protocols.swift |
Tests protocols and conformances. |
unified/ql/test/library-tests/type-inference/pattern_matching.swift |
Tests pattern-bound types. |
unified/ql/test/library-tests/type-inference/overload_resolution.swift |
Tests overload resolution. |
unified/ql/test/library-tests/type-inference/lub.swift |
Tests least-upper-bound inference. |
unified/ql/test/library-tests/type-inference/key_paths.swift |
Covers key-path scenarios. |
unified/ql/test/library-tests/type-inference/generics.swift |
Tests generic declarations and calls. |
unified/ql/test/library-tests/type-inference/fields.swift |
Tests field resolution. |
unified/ql/test/library-tests/type-inference/CONSISTENCY/CfgConsistency.expected |
Updates consistency expectations. |
unified/ql/test/library-tests/type-inference/closures.swift |
Tests closure typing and invocation. |
unified/ql/test/library-tests/type-inference/classes.swift |
Tests classes, inheritance, and methods. |
unified/ql/test/library-tests/type-inference/basics.swift |
Tests foundational inference behavior. |
unified/ql/test/library-tests/dataflow/test.expected |
Updates dataflow expectations. |
unified/ql/test/library-tests/dataflow/calls.swift |
Adds resolved-call flow cases. |
unified/ql/test/library-tests/BasicTest/test.ql |
Filters built-in nodes from tests. |
unified/ql/lib/utils/test/TestUtils.qll |
Adds tuple and callable naming helpers. |
unified/ql/lib/utils/test/ExternalLocationPostProcessing.ql |
Normalizes external type locations. |
unified/ql/lib/qlpack.yml |
Adds the type-inference dependency. |
unified/ql/lib/codeql/unified/internal/typeinference/TypeMention.qll |
Models type mentions and aliases. |
unified/ql/lib/codeql/unified/internal/typeinference/TypeInferencePluginSwift.qll |
Moderate (4 votes): Binary expressions incorrectly inherit the common operand type, including comparison and equality expressions whose result should be Bool; result-changing operators must be handled separately without guessing for custom operators. |
unified/ql/lib/codeql/unified/internal/typeinference/TypeInferencePlugin.qll |
Defines language-plugin interfaces. |
unified/ql/lib/codeql/unified/internal/typeinference/TypeInferenceConsistency.qll |
Exposes inference consistency checks. |
unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll |
Moderate (1 vote): Function-valued field invocation remains a target when a direct callable member exists, creating incorrect call and dataflow edges; suppress that branch when a direct target is found. |
unified/ql/lib/codeql/unified/internal/typeinference/TypeAbstraction.qll |
Models generic type abstractions. |
unified/ql/lib/codeql/unified/internal/typeinference/Type.qll |
Moderate (1 vote): TypeParameterType.getDeclaringItem() only handles class-like declarations, omitting function and type-alias parameters; return the actual enclosing declaration. |
unified/ql/lib/codeql/unified/internal/FacadeAst.qll |
Adds tuple and closure helpers. |
unified/ql/lib/codeql/unified/internal/ExprPositionsPluginSwift.qll |
Adds Swift type-context handling. |
unified/ql/lib/codeql/unified/internal/ExprPositionsPlugin.qll |
Defines type-context plugin hooks. |
unified/ql/lib/codeql/unified/internal/ExprPositions.qll |
Expands type-context recognition. |
unified/ql/lib/codeql/unified/internal/dataflow/CallGraph.qll |
Moderate (1 vote): Overload-agnostic targets are wired directly into dataflow, permitting flow through unselected same-name overloads; require compatible or unique target filtering. |
unified/ql/consistency-queries/TypeInferenceConsistency.ql |
Registers inference diagnostics. |
shared/typeinference/codeql/typeinference/internal/TypeInference.qll |
Adjusts shared inference propagation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
8d76018 to
5fd9af6
Compare
5fd9af6 to
0c4c11a
Compare
0c4c11a to
fa6d1e4
Compare
asgerf
left a comment
There was a problem hiding this comment.
Just some observations so far. Will take another look on Monday.
It's quite hard to review the instantiation honestly. It's a collection of plausible-sounding AST class adapters. I have no idea how much of it works.
I'm a little worried about what it would take to support destructuring, as the Declaration interface seems unable to cope with it.
They should all work; it's only
Destructuring is not expected to work with the |

This PR adds the first version of type inference and type-inference-based call resolution for Unified/Swift. The PR adds a lot of test cases (some of which are copied over from the current Swift implementation, where the annotations have been checked by the Swift compiler), which make up the bulk of the diff of this PR.
Using the shared type inference library, we support already a lot of aspects, for example sub typing and contextual typing (including contextual typing of closures), but there are still a lot of aspects that remain to be handled (a full list of known shortcomings is in the header of
TypeInference.qll), for example overloading and pattern matching.DCA looks great:
Percentage of calls with call targetincreases from 11.5 % to 24.4 % (and as a result more cleartext-logging results) while there is only very little performance impact.