Files
kotlin-fork/compiler/testData/diagnostics/tests/inference/commonSystem/postponedCompletionWithExactAnnotation.kt
T
Mikhail Zarechenskiy 796cdea50e [NI] Require all proper constraints for Exact return type
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
2019-06-19 11:07:31 +03:00

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
)
}