Pros:
* <obinit> no longer emitted: one less function per class
* Parameters to the primary constructor, if any, are no longer referred to out of scope
* Simple primary constructor `val` and `var` declarations work as expected
Cons:
* If there are multiple secondary constructors, no primary constructor and long init blocks, there could be considerable duplicate extraction of those init blocks. Hopefully this case is very rare.
These are extracted as "throw new kotlin.NoWhenBranchFoundException();", which is the Java lowering of the intrinsic.
In the process, amend the control-flow graph to let when branches propagate `throw`s outwards, and similarly statement expressions.
- Create a new operator representing an infix value [in]equality test, equivalent to Objects.equals(lhs, rhs)
- Continue to use simple equality where it is clearly possible at the callsite
- Note that ieee754equals is the same as Java's == and != operators
If it is used by the compiler to implement the infix plus operator, resugar it and extract a `+` as Java would. If it is literally called by the user (e.g. `(if (x) then "not null" else null).plus(something)`), then extract a call to the real method Intrinsics.stringPlus (a two-arg static method).