Expression will be checked against expected type later.
Theoretically, this is not very good, but it aligns with the old
inference, plus it helps avoiding multiple type mismatch diagnostics.
Consider common supertype of `S` and `Nothing`, where `S` has nullable
upper bound or it's flexible. Before the fix, result was `S?`, which
is correct but too conservative. Now, we'll preserve nullability of
resulting type if it's already nullable.
This happened because we were failing to find path of not-nullable
types from `Nothing` to `S`, which should obviously exists by
semantics of Nothing
The design is to use `suspend fun` instead of coercion, just as suspend
lambdas.
However, this syntax is not supported in the parser. But this is not a
problem, since the coercion lead to internal compiler error.
As a workaround everybody uses suspend lambdas.
#KT-24860: Fixed
See `checkStatementType`, we return `null` to reduce count of errors.
Also, note that named function which is used as last statement in lambda
doesn't coerce to Unit, this is a separate bug and will be addressed later,
see #KT-25383
#EA-121026 Fixed
During subtyping/incorporation we transform types (e.g. changing nullability,
form of the type) and, basically, we're doing this to some FIXPOINT.
It's important that we use `KotlinType.hashCode()` to compare types, but
for error types hashCode is a hashCode of its supertype and, for example,
`makeNullableAsSpecified` method recreate type every time. So, we continue
to generate new constraints and we'll never stop incorporation algorithm
Consider following case:
fun foo(): Unit = run { "hello" }
Previously, NI would analyze lambda body without expected type, because
it is a type variable 'R' from 'run', which hasn't been fixed yet. This
leads to treating "hello" as lambda-return argument and adding bogus
'String' constraint on 'R', and, consequently, type mismatch.
Now, we peek into current constraint system and check if return-type of
lambda is type variable with upper-Unit constraint (which is exactly
condition for its body to be Unit-coerced). If so, then we provide
expected Unit-type for body explicitly, and the rest will be done
automatically (in particular, in aforementioned example "hello" wouldn't
be treated as lambda return argument).