796cdea50e
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
29 lines
787 B
Kotlin
Vendored
29 lines
787 B
Kotlin
Vendored
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
|
// !LANGUAGE: -NewInference
|
|
|
|
interface ISample
|
|
|
|
fun <K> elvisSimple(x: K?, y: K): K = y
|
|
|
|
@Suppress("INVISIBLE_REFERENCE")
|
|
fun <K> elvisExact(x: K?, y: K): @kotlin.internal.Exact K = y
|
|
|
|
fun <T : Number> materialize(): T? = TODO()
|
|
|
|
fun test(nullableSample: ISample, any: Any) {
|
|
<!DEBUG_INFO_EXPRESSION_TYPE("ISample")!>elvisSimple(
|
|
nullableSample,
|
|
<!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>materialize<!>()
|
|
)<!>
|
|
|
|
elvisSimple(
|
|
<!DEBUG_INFO_EXPRESSION_TYPE("ISample")!>elvisSimple(nullableSample, <!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>materialize<!>())<!>,
|
|
any
|
|
)
|
|
|
|
elvisSimple(
|
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>elvisExact(nullableSample, materialize())<!>,
|
|
any
|
|
)
|
|
}
|