Skip to content

Unified: Type inference first version - #22639

Merged
hvitved merged 5 commits into
github:mainfrom
hvitved:unified/type-inference
Sep 28, 2026
Merged

hvitved merged 5 commits into
github:mainfrom
hvitved:unified/type-inference

Conversation

@hvitved

@hvitved hvitved commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

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 target increases from 11.5 % to 24.4 % (and as a result more cleartext-logging results) while there is only very little performance impact.

private import TypeMention
private import TypeInference
private import TypeInference::Consistency as Consistency
import TypeInference::Consistency
@github-actions github-actions Bot added Rust Pull requests that update Rust code Swift labels Sep 21, 2026
@hvitved
hvitved force-pushed the unified/type-inference branch 2 times, most recently from 9adf294 to bbc8b9a Compare September 21, 2026 12:58
@github-actions github-actions Bot removed the Swift label Sep 21, 2026
@hvitved
hvitved force-pushed the unified/type-inference branch 4 times, most recently from e71b6f6 to 5886197 Compare September 22, 2026 09:58
* parameter.
*/
bindingset[t, arity, i]
abstract predicate functionInvokeSignature(Type t, int arity, int i, int j, TypePath path);
@hvitved
hvitved force-pushed the unified/type-inference branch from 5886197 to b2b2531 Compare September 22, 2026 10:04
@github-actions github-actions Bot added the Swift label Sep 22, 2026
@hvitved
hvitved force-pushed the unified/type-inference branch 2 times, most recently from ab9a603 to 76692f4 Compare September 22, 2026 13:35
@github-actions github-actions Bot removed the Swift label Sep 22, 2026
@hvitved
hvitved force-pushed the unified/type-inference branch from 76692f4 to c5db7b1 Compare September 22, 2026 14:38
@hvitved hvitved changed the title Unified: Basic type inference Unified: Type inference first version Sep 22, 2026
@hvitved
hvitved force-pushed the unified/type-inference branch 5 times, most recently from fe9c6eb to ebbac0e Compare September 23, 2026 12:08
}

/** 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 |
@github-actions github-actions Bot removed the Rust Pull requests that update Rust code label Sep 23, 2026
@hvitved
hvitved force-pushed the unified/type-inference branch from ebbac0e to 228fe9c Compare September 23, 2026 13:46
@hvitved
hvitved force-pushed the unified/type-inference branch from 228fe9c to a159ea5 Compare September 24, 2026 08:34
@hvitved
hvitved force-pushed the unified/type-inference branch 2 times, most recently from e58e192 to 8d76018 Compare September 24, 2026 11:03
@hvitved
hvitved requested a balanced review from Copilot September 24, 2026 11:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 Medium severity

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.

@hvitved
hvitved force-pushed the unified/type-inference branch from 8d76018 to 5fd9af6 Compare September 24, 2026 14:52
@hvitved hvitved added the no-change-note-required This PR does not need a change note label Sep 25, 2026
@hvitved
hvitved marked this pull request as ready for review September 25, 2026 07:57
@hvitved
hvitved requested review from a team as code owners September 25, 2026 07:57
@hvitved
hvitved requested a review from asgerf September 25, 2026 07:59
@hvitved
hvitved force-pushed the unified/type-inference branch from 5fd9af6 to 0c4c11a Compare September 25, 2026 08:27
@hvitved
hvitved force-pushed the unified/type-inference branch from 0c4c11a to fa6d1e4 Compare September 25, 2026 08:36

@asgerf asgerf left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread unified/ql/lib/codeql/unified/internal/ExprPositions.qll Outdated
Comment thread unified/ql/lib/codeql/unified/internal/typeinference/Type.qll Outdated
Comment thread unified/ql/lib/codeql/unified/internal/typeinference/TypeInferencePluginSwift.qll Outdated
Comment thread unified/ql/lib/utils/test/TestUtils.qll Outdated
@hvitved

hvitved commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

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.

They should all work; it's only ParenExpr that is none().

I'm a little worried about what it would take to support destructuring, as the Declaration interface seems unable to cope with it.

Destructuring is not expected to work with the Declaration interface as-is. Rust currently has specific logic for this, which I plan to move into the shared library.

@hvitved
hvitved merged commit e387ca4 into github:main Sep 28, 2026
109 of 112 checks passed
@hvitved
hvitved deleted the unified/type-inference branch September 28, 2026 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-change-note-required This PR does not need a change note

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants