Incorporate PR from Steven Schäfer into IrType-based implicit cast
insertion (commit 17b925636e8717e7648c5d7b792c6ab4d18f776d).
NB this still uses originalKotlinType to determine if the type was
nullability flexible. It is somewhat error-prone and something we want
to get rid of. However, it boils down to some design questions related
to implicit null checks in Kotlin - e.g., it might be Ok to just treat
nullability flexible type `T!` as `T?` in IR, generate null checks for
all usages of type `T?` where a non-null type is expected, and later
eliminate the null checks that are redundant according to the (quite
conservative) criterion in the redundant null check elimination.
Before this commit, implicit Unit type for function with body and
without type, implicit Boolean type for conditions etc. were 'implicit'
types and resolved types together.
Sometimes this could lead to hard-to-find issues in FIR resolve, because
'implicit' types are usually handled there as 'necessary to resolve'
which is wrong for such effectively-resolved types.
This commit influences enum entries deserialization.
In particular, now we don't deserialize enum entry members,
but deserialize its supertype correctly (see test data changes).
Before this commit, explicit extension receiver type check was performed
during found candidates analysis (together with arguments type check etc.)
Now we do it just after candidate is found, and filter the candidate
out if explicit receiver type is inappropriate.
This commit slightly changes resolve semantics,
replacing WRONG_RECEIVER with UNRESOLVED_REFERENCE in certain situations.
However, it provides significant performance boost.
Consider call `foo(bar())` where bar() returns some type variable `T`;
We had a contract that call `bar` can be completed without completion
of foo (type variables can be inferred from the current context) if `T`
has at least one proper lower constraint (ProperType <: T).
Indeed, new constraints can be added only as upper ones, so there is
no need to grow constraint system.
Unfortunately, we have Exact annotation that is used on return type of
elvis. Now, consider the following situation:
```
fun foo(a: Any) {}
fun bar(e: T): @Exact T
foo(bar("str"))
```
Here, because of Exact annotation, constraint with `Any`-type will be
added as an equal one => our prerequisite that there will be no new
lower constraints is false. `bar("str")` is inferred to Any in OI,
this seems conceptually wrong, but it's another topic of discussion.
In NI we can't just grow constraint system to use outer call because
of another important use-case:
```
fun <T> generic(i: Inv<T>) {}
fun test(a: Inv<*>?, b: Inv<*>) {
generic(a ?: b)
}
```
Common constraint system for these two calls can't be solved
(fundamentally) for this example, only if (a ?: b) and generic(result)
are computed separately.
So, to mitigate initial issue, we'll grow constraint system only if
there is at least one non-proper constraint.
#KT-31969 Fixed