Tech News
← Back to articles

Roadmap for Improving the Type Checker

read original related products more articles

Roadmap for improving the type checker

In the past, we've released various "manifestos" and "roadmaps" to discuss planned improvements to the language. This post is also a roadmap of sorts, but instead, the focus is on the implementation rather than user-visible language changes (however, I will briefly mention a few potential language changes at the very end).

Specifically, I'm going to talk about some work we are doing to improve expression type checking in the Swift compiler. This includes changes that have already shipped in Swift 6.2, changes that are on the main development branch, changes that we plan on working on next, and more tentative longer-term plans.

Before talking about specific improvements, I'm going to start with a rather long explanation of this part of the compiler implementation, which to my knowledge has not been summarized in one place yet.

Introduction

This is all, of course, about the dreaded the compiler is unable to type-check this expression in reasonable time error. This error can appear with both valid and invalid code, and the various workarounds are unsatisfactory, to say the least. Splitting up an expression into smaller pieces, introducing type annotations, or attempting other refactorings will sometimes allow valid code to type check, or in the invalid case, surface an actionable diagnostic. However, this breaks flow and becomes a frustrating process of trial and error "shotgun debugging" even for the most experienced Swift programmers. The compiler doesn't even tell you if your expression is valid or not!

Type-based overloading

Swift supports overloading, where multiple declarations in the same scope can share the same name. Swift allows two forms of overloading: by argument labels, or by type. The former case is ultimately handled by name lookup, because argument labels are specified at the call site. Argument label lookup does not introduce any algorithmic complexity in the type checker, so I won't discuss it further. Type-based overloading, on the other hand, requires the type checker to reason about the types of expressions before it can decide the correct overload to pick, which is a more difficult problem. So in the rest of this post, when I talk about overloading, I'm specifically referring to overloading based on types---either parameter or result types.

Constraint solving

The Swift compiler implements overload resolution by transforming expression type checking into a constraint solving problem. The compiler always looks at a single expression at a time (with some exceptions, such as multi-statement closures), and proceeds to type-check each expression in turn.

... continue reading