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).
Previously, there was receiver of type Nothing, which could case result
of the call to be inferred to Nothing too. This could case bogus
UNREACHABLE_CODE diagnostics in cases like this:
```
fun <T> id(x: T) = x
fun test() {
id(unresolvedReference) // type of statement is 'Nothing'
// ... everything here is marked as unreachable ...
}
```
This commit changes type of receiver for such calls form Nothing to
ErrorType.
This commits introduces testdata changes, where NI behaviour strictly
improved, after several previous fixes.
For some tests, just WITH_NEW_INFERENCE directive was added. It
indicates, that some of previous commits first introduced error in that
test, and then some other commit fixed it (netting no overall testdata
change). It is preferrably to keep those annotations until we will
migrate to NI completely, to prevent unexpected regressions.