Semantic Diff

#9259 Read fields of a variable-free object without copying its type

2 commits

bf35764db1628906bf68c424735c68da4d1711fb..pr-9259

426355dd8 · cknitt + Claude · Nov 07, 2026, 10:06 UTC

Read fields of a variable-free object without copying its type

Why

Each o["f"] instantiated the whole type of o, and the .cmt file stored every copy, so reading each field of an object with n fields once cost O(n²): 800 fields allocated 77M words and took 0.87 s. They now allocate 6.5M words and take 0.06 s.

When the identifier's type is generic and has no type variables, a copy would be identical, so the identifier keeps the type itself and only the field's type is instantiated. Looking up a field that the type has doesn't change it. Types with variables are still copied.

41ad3b035 · cknitt + Claude · Nov 07, 2026, 19:05 UTC

Type the object of a field read through its own identifier helper

The benchmarks showed every expression allocating a little more (up to 0.17%), because the new optional argument of type_expect was captured by the closure it builds for each expression. Identifiers are now typed by type_ident, which the field read calls directly for a bare identifier, so type_expect is as before.