Reading Kotlin compiler source: advices?


I like Kotlin and is a PL implementation enthusiast. I was trying to understand the high-level architecture of the Kotlin compiler, with an emphasis on the type checker (e.g. how is Kotlin type checking / inference implemented?), and aiming at ultimately contributing code back to it. And since ther is scarce resource about Kotlin internals, I have to resort to reading its source. Would anyone that has worked with Kotlin compiler give some pointers?

So far I’ve skimmed through the core and the frontend module. Below are my findings: Correct me if I’m wrong – I see that the compilation pipeline has roughtly 3 stages and each stage has a set of key IR types: DeclarationDescriptor / KotlinType (high level IR tree / types and metadata) -> FirElement / FirBasedSymbol (intermediate level IR / types and metadata) -> IrElement / IrSymbol (low level IR / types and metadata). Are these stages documented somewhere? What are the key differences between these IRs?

Each stage has its own type system (Classic for descriptor, Cone for FIR, and IrTypeSystem for IR). They deal with type equality, constraint checking, substitution/unification. Are these type systems documented somewhere?

There are a bunch of analyzers that lowers a set of IR to the next stage: LazyTopDownAnalyzer converts Psi-based KtElement (input AST) into descriptors (e.g. class defs are turned into LazyClassDescriptor). The analyzer looks straightforward – it just deals with all the top-level declarations in a specific order.

I know that this question might be too broad… I guess I just wanted to see if anyone has done this before, or if there is any pointers to understanding Kotlin internals. Thanks!

Edit: found Any docs on Kotlin internals? which talks about binding analysis (BindingTrace and BindingContext), which I guess I should take a look at.

1 Like

Just be aware. That document is from '13. The compiler architecture has undergone (is undergoing) a major rewrite on two areas:

  • The use of an IR to share front-end between all backends (jvm,js,native) – and allow IR to be used for inline functions etc.
  • A sane plugin API. This is a saner API for compiler plugins that is under development, but not quite finalised even for experimental access (and not documented either)

There may be further changes that I’m not aware of at all.

Edit 2: I’ve been slowly reading through the codebase and taking notes in case anyone is interested as well.


It should be noted that Kotlin is having it’s type inference reworked.

Kotlin is a wonderful language but jetbrains should involve more into investing in open source contributors, it should pay off.

But for people to contribute to the compiler, they need among other things, a guide.
Such a guide should take inspiration from probably the biggest community driven compiler: rustc

1 Like

Yes I agree completely. I’m writing a compiler myself and I am using kotlin’s IR as inspiration for my IR. It’s really crazy cause I see the symbol table and the IR is kinda all over the place. Just wish they would at least document the source code with KDocs