visitTypeInsn
A type instruction naming a class a snippet cannot is itself access-checked. Each of the three with a fixed stack shape therefore moves into the bridge, which loads the class by name, where loading is not access-checked, and keeps the instruction's own semantics:
CHECKCAST: the same check, still an Object, or an array of Object, to the verifier. It cannot stay as written: kotlinc emits one on its own wherever a value flows into a slot of that type. Most are upcasts, but an
as, or a value read out of a generic container, is a real check.INSTANCEOF:
isandas?.ANEWARRAY: a real array of that class, typed as an array of Object. A class literal,
::class, moves into the bridge too: see visitLdcInsn. Andwhen (x) { is ... }is one of these INSTANCEOFs, PlainEngine compiling it as a chain of type checks.
NEW stays as written, deliberately: its uninitialized object lives across the whole argument list, so carrying it would mean lifting each NEW out of its arguments — far more rewriting than a snippet that creates a non-public class is worth. So does a catch of one, deliberately too: it is an exception-table entry, not an instruction, and carrying it would mean rewriting the handler. Both fail with IllegalAccessError.