Hack: do not add trivial constraints (t <: Any?) for constituent types,
otherwise nested calls handling logic in old inference wouldn't work for type alias constructors.
This commit is contained in:
+7
-1
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
@@ -136,8 +137,13 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
||||
) {
|
||||
val substitutedType = substitutedArgument.type
|
||||
for (upperBound in typeParameter.upperBounds) {
|
||||
val substitutedUpperBound = boundsSubstitutor.safeSubstitute(upperBound, Variance.INVARIANT)
|
||||
val substitutedUpperBound = boundsSubstitutor.safeSubstitute(upperBound, Variance.INVARIANT).upperIfFlexible()
|
||||
val constraintPosition = ValidityConstraintForConstituentType(substitutedType, typeParameter, substitutedUpperBound)
|
||||
|
||||
// Do not add extra constraints if upper bound is 'Any?';
|
||||
// otherwise it will be treated incorrectly in nested calls processing.
|
||||
if (KotlinBuiltIns.isNullableAny(substitutedUpperBound)) continue
|
||||
|
||||
builder.addSubtypeConstraint(substitutedType, substitutedUpperBound, constraintPosition)
|
||||
}
|
||||
}
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
interface Ref<T> {
|
||||
var x: T
|
||||
}
|
||||
|
||||
class LateInitNumRef<NN: Number>() : Ref<NN> {
|
||||
constructor(x: NN) : this() { this.x = x }
|
||||
|
||||
private var xx: NN? = null
|
||||
|
||||
override var x: NN
|
||||
get() = xx!!
|
||||
set(value) {
|
||||
xx = value
|
||||
}
|
||||
}
|
||||
|
||||
typealias LateNR<Nt> = LateInitNumRef<Nt>
|
||||
|
||||
fun <V, R : Ref<in V>> update(r: R, v: V): R {
|
||||
r.x = v
|
||||
return r
|
||||
}
|
||||
|
||||
val r1 = update(LateInitNumRef(), 1)
|
||||
val r1a = update(LateNR(), 1)
|
||||
val r2 = update(LateInitNumRef(1), 1)
|
||||
val r2a = update(LateNR(1), 1)
|
||||
val r3 = LateInitNumRef(1)
|
||||
val r3a = LateNR(1)
|
||||
|
||||
fun test() {
|
||||
r1.x = <!TYPE_MISMATCH!>r1.x<!>
|
||||
r1a.x = <!TYPE_MISMATCH!>r1a.x<!>
|
||||
r2.x = r2.x
|
||||
r2a.x = r2a.x
|
||||
r3.x = r3.x
|
||||
r3a.x = r3a.x
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package
|
||||
|
||||
public val r1: Ref<in kotlin.Int>
|
||||
public val r1a: Ref<in kotlin.Int>
|
||||
public val r2: LateInitNumRef<kotlin.Int>
|
||||
public val r2a: LateInitNumRef<kotlin.Int>
|
||||
public val r3: LateInitNumRef<kotlin.Int>
|
||||
public val r3a: LateInitNumRef<kotlin.Int>
|
||||
public fun test(): kotlin.Unit
|
||||
public fun </*0*/ V, /*1*/ R : Ref<in V>> update(/*0*/ r: R, /*1*/ v: V): R
|
||||
|
||||
public final class LateInitNumRef</*0*/ NN : kotlin.Number> : Ref<NN> {
|
||||
public constructor LateInitNumRef</*0*/ NN : kotlin.Number>()
|
||||
public constructor LateInitNumRef</*0*/ NN : kotlin.Number>(/*0*/ x: NN)
|
||||
public open override /*1*/ var x: NN
|
||||
private final var xx: NN?
|
||||
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 interface Ref</*0*/ T> {
|
||||
public abstract var x: 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 typealias LateNR</*0*/ Nt> = LateInitNumRef<Nt>
|
||||
@@ -0,0 +1,20 @@
|
||||
import kotlin.test.*
|
||||
import java.util.*
|
||||
|
||||
typealias HM<Kt, Vt> = HashMap<Kt, Vt>
|
||||
|
||||
fun <K, V, M : MutableMap<in K, MutableList<V>>> updateMap(map: M, k: K, v: V): M {
|
||||
map[k]!!.add(v)
|
||||
return map
|
||||
}
|
||||
|
||||
val nameToTeam = listOf("Alice" to "Marketing", "Bob" to "Sales", "Carol" to "Marketing")
|
||||
val namesByTeam = nameToTeam.groupBy({ it.second }, { it.first })
|
||||
|
||||
val mutableNamesByTeam1 = updateMap(HM(), "", "")
|
||||
val mutableNamesByTeam2 = updateMap(HashMap(), "", "")
|
||||
|
||||
fun test() {
|
||||
assertEquals(namesByTeam, mutableNamesByTeam1)
|
||||
assertEquals(namesByTeam, mutableNamesByTeam2)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package
|
||||
|
||||
public val mutableNamesByTeam1: java.util.HashMap<kotlin.String, kotlin.collections.MutableList<kotlin.String>>
|
||||
public val mutableNamesByTeam2: java.util.HashMap<kotlin.String, kotlin.collections.MutableList<kotlin.String>>
|
||||
public val nameToTeam: kotlin.collections.List<kotlin.Pair<kotlin.String, kotlin.String>>
|
||||
public val namesByTeam: kotlin.collections.Map<kotlin.String, kotlin.collections.List<kotlin.String>>
|
||||
public fun test(): kotlin.Unit
|
||||
public fun </*0*/ K, /*1*/ V, /*2*/ M : kotlin.collections.MutableMap<in K, kotlin.collections.MutableList<V>>> updateMap(/*0*/ map: M, /*1*/ k: K, /*2*/ v: V): M
|
||||
public typealias HM</*0*/ Kt, /*1*/ Vt> = java.util.HashMap<Kt, Vt>
|
||||
@@ -21064,6 +21064,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("typeAliasConstructorTypeArgumentsInferenceWithNestedCalls2.kt")
|
||||
public void testTypeAliasConstructorTypeArgumentsInferenceWithNestedCalls2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typeAliasConstructorTypeArgumentsInferenceWithNestedCalls2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("typeAliasConstructorTypeArgumentsInferenceWithPhantomTypes.kt")
|
||||
public void testTypeAliasConstructorTypeArgumentsInferenceWithPhantomTypes() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typeAliasConstructorTypeArgumentsInferenceWithPhantomTypes.kt");
|
||||
|
||||
@@ -1304,6 +1304,12 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("hashMapTypeAlias.kt")
|
||||
public void testHashMapTypeAlias() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/typealias/hashMapTypeAlias.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("typeAliasSamAdapterConstructors.kt")
|
||||
public void testTypeAliasSamAdapterConstructors() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/typealias/typeAliasSamAdapterConstructors.kt");
|
||||
|
||||
Reference in New Issue
Block a user