[NI] Introduce flag to change constraint system for overload resolution
This commit doesn't change behaviour of any inference algorithm, it introduces opportunity to switch constraint system that is used for overload resolution and fix problematic cases by changing one enum entry. Due to fundamental changes, there are cases where a new inference algorithm reports overload resolution ambiguity errors (#KT-31670, #KT-31758), which is correct from its point of view. However, this is a breaking change and to really make it, we should be very confident and have enough motivation for it, therefore, we don't change behavior now in order to collect more examples (if there are any). And if we find a lot of erroneous examples, we'll be able to change the behavior quite simply
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
// !CONSTRAINT_SYSTEM_FOR_OVERLOAD_RESOLUTION: CONSTRAINT_SYSTEM_FOR_NEW_INFERENCE
|
||||
|
||||
open class A<T>(val value: T)
|
||||
class B<T>(value: T) : A<T>(value)
|
||||
|
||||
fun <T> A<T>.foo(block: (T?) -> Unit) {
|
||||
block(value)
|
||||
}
|
||||
fun <T> B<T>.foo(block: (T) -> Unit) {
|
||||
block(value)
|
||||
}
|
||||
|
||||
fun main() {
|
||||
B("string").<!NI;OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!> { }
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package
|
||||
|
||||
public fun main(): kotlin.Unit
|
||||
public fun </*0*/ T> A<T>.foo(/*0*/ block: (T?) -> kotlin.Unit): kotlin.Unit
|
||||
public fun </*0*/ T> B<T>.foo(/*0*/ block: (T) -> kotlin.Unit): kotlin.Unit
|
||||
|
||||
public open class A</*0*/ T> {
|
||||
public constructor A</*0*/ T>(/*0*/ value: T)
|
||||
public final val value: T
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class B</*0*/ T> : A<T> {
|
||||
public constructor B</*0*/ T>(/*0*/ value: T)
|
||||
public final override /*1*/ /*fake_override*/ val value: T
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
// !CONSTRAINT_SYSTEM_FOR_OVERLOAD_RESOLUTION: CONSTRAINT_SYSTEM_FOR_OLD_INFERENCE
|
||||
|
||||
open class A<T>(val value: T)
|
||||
class B<T>(value: T) : A<T>(value)
|
||||
|
||||
fun <T> A<T>.foo(block: (T?) -> Unit) {
|
||||
block(value)
|
||||
}
|
||||
fun <T> B<T>.foo(block: (T) -> Unit) {
|
||||
block(value)
|
||||
}
|
||||
|
||||
fun main() {
|
||||
B("string").foo { }
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package
|
||||
|
||||
public fun main(): kotlin.Unit
|
||||
public fun </*0*/ T> A<T>.foo(/*0*/ block: (T?) -> kotlin.Unit): kotlin.Unit
|
||||
public fun </*0*/ T> B<T>.foo(/*0*/ block: (T) -> kotlin.Unit): kotlin.Unit
|
||||
|
||||
public open class A</*0*/ T> {
|
||||
public constructor A</*0*/ T>(/*0*/ value: T)
|
||||
public final val value: T
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class B</*0*/ T> : A<T> {
|
||||
public constructor B</*0*/ T>(/*0*/ value: T)
|
||||
public final override /*1*/ /*fake_override*/ val value: T
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
// !CONSTRAINT_SYSTEM_FOR_OVERLOAD_RESOLUTION: CONSTRAINT_SYSTEM_FOR_NEW_INFERENCE
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
// FILE: a.kt
|
||||
|
||||
package a
|
||||
|
||||
enum class A { A1 }
|
||||
|
||||
fun <T : Enum<T>> foo(arg: T.() -> Unit) = 1
|
||||
|
||||
// FILE: b.kt
|
||||
|
||||
package b
|
||||
|
||||
fun <T : Any> foo(arg: T.() -> Unit) = 2
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
import a.*
|
||||
import b.*
|
||||
|
||||
fun test() {
|
||||
<!NI;OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!><A> { }
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package
|
||||
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
package a {
|
||||
public fun </*0*/ T : kotlin.Enum<T>> foo(/*0*/ arg: T.() -> kotlin.Unit): kotlin.Int
|
||||
|
||||
public final enum class A : kotlin.Enum<a.A> {
|
||||
enum entry A1
|
||||
|
||||
private constructor A()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: a.A): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<a.A!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): a.A
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<a.A>
|
||||
}
|
||||
}
|
||||
|
||||
package b {
|
||||
public fun </*0*/ T : kotlin.Any> foo(/*0*/ arg: T.() -> kotlin.Unit): kotlin.Int
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
// !CONSTRAINT_SYSTEM_FOR_OVERLOAD_RESOLUTION: CONSTRAINT_SYSTEM_FOR_OLD_INFERENCE
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
// FILE: a.kt
|
||||
|
||||
package a
|
||||
|
||||
enum class A { A1 }
|
||||
|
||||
fun <T : Enum<T>> foo(arg: T.() -> Unit) = 1
|
||||
|
||||
// FILE: b.kt
|
||||
|
||||
package b
|
||||
|
||||
fun <T : Any> foo(arg: T.() -> Unit) = 2
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
import a.*
|
||||
import b.*
|
||||
|
||||
fun test() {
|
||||
foo<A> { }
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package
|
||||
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
package a {
|
||||
public fun </*0*/ T : kotlin.Enum<T>> foo(/*0*/ arg: T.() -> kotlin.Unit): kotlin.Int
|
||||
|
||||
public final enum class A : kotlin.Enum<a.A> {
|
||||
enum entry A1
|
||||
|
||||
private constructor A()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: a.A): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<a.A!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): a.A
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<a.A>
|
||||
}
|
||||
}
|
||||
|
||||
package b {
|
||||
public fun </*0*/ T : kotlin.Any> foo(/*0*/ arg: T.() -> kotlin.Unit): kotlin.Int
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
// !CONSTRAINT_SYSTEM_FOR_OVERLOAD_RESOLUTION: CONSTRAINT_SYSTEM_FOR_NEW_INFERENCE
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
// FILE: a.kt
|
||||
|
||||
package a
|
||||
|
||||
fun <T> foo(block: (T?) -> Unit) {}
|
||||
|
||||
// FILE: b.kt
|
||||
|
||||
package b
|
||||
|
||||
fun <K> foo(block: (K) -> Unit) {}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
import a.*
|
||||
import b.*
|
||||
|
||||
fun main() {
|
||||
<!OI;OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!><String> { }
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
public fun main(): kotlin.Unit
|
||||
|
||||
package a {
|
||||
public fun </*0*/ T> foo(/*0*/ block: (T?) -> kotlin.Unit): kotlin.Unit
|
||||
}
|
||||
|
||||
package b {
|
||||
public fun </*0*/ K> foo(/*0*/ block: (K) -> kotlin.Unit): kotlin.Unit
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
// !CONSTRAINT_SYSTEM_FOR_OVERLOAD_RESOLUTION: CONSTRAINT_SYSTEM_FOR_OLD_INFERENCE
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
// FILE: a.kt
|
||||
|
||||
package a
|
||||
|
||||
fun <T> foo(block: (T?) -> Unit) {}
|
||||
|
||||
// FILE: b.kt
|
||||
|
||||
package b
|
||||
|
||||
fun <K> foo(block: (K) -> Unit) {}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
import a.*
|
||||
import b.*
|
||||
|
||||
fun main() {
|
||||
<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!><String> { }
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
public fun main(): kotlin.Unit
|
||||
|
||||
package a {
|
||||
public fun </*0*/ T> foo(/*0*/ block: (T?) -> kotlin.Unit): kotlin.Unit
|
||||
}
|
||||
|
||||
package b {
|
||||
public fun </*0*/ K> foo(/*0*/ block: (K) -> kotlin.Unit): kotlin.Unit
|
||||
}
|
||||
Reference in New Issue
Block a user