Fix detecting upper bounds of generics of typealiases constructors in NI
This commit is contained in:
+34
-2
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
||||
@@ -21,6 +22,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.InfixCallNoInfixModifier
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.InvokeConventionCallNoOperatorModifier
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.checker.anySuperTypeConstructor
|
||||
@@ -185,13 +187,42 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
||||
csBuilder.registerVariable(freshVariable)
|
||||
}
|
||||
|
||||
fun TypeVariableFromCallableDescriptor.addSubtypeConstraint(
|
||||
upperBound: KotlinType,
|
||||
position: DeclaredUpperBoundConstraintPosition
|
||||
) {
|
||||
csBuilder.addSubtypeConstraint(defaultType, toFreshVariables.safeSubstitute(upperBound.unwrap()), position)
|
||||
}
|
||||
|
||||
for (index in typeParameters.indices) {
|
||||
val typeParameter = typeParameters[index]
|
||||
val freshVariable = freshTypeVariables[index]
|
||||
val position = DeclaredUpperBoundConstraintPosition(typeParameter)
|
||||
|
||||
for (upperBound in typeParameter.upperBounds) {
|
||||
csBuilder.addSubtypeConstraint(freshVariable.defaultType, toFreshVariables.safeSubstitute(upperBound.unwrap()), position)
|
||||
freshVariable.addSubtypeConstraint(upperBound, position)
|
||||
}
|
||||
}
|
||||
|
||||
if (candidateDescriptor is TypeAliasConstructorDescriptor) {
|
||||
val typeAliasDescriptor = candidateDescriptor.typeAliasDescriptor
|
||||
val originalTypes = typeAliasDescriptor.underlyingType.arguments.map { it.type }
|
||||
val originalTypeParameters = candidateDescriptor.underlyingConstructorDescriptor.typeParameters
|
||||
for (index in typeParameters.indices) {
|
||||
val typeParameter = typeParameters[index]
|
||||
val freshVariable = freshTypeVariables[index]
|
||||
val typeMapping = originalTypes.mapIndexedNotNull { i: Int, kotlinType: KotlinType ->
|
||||
if (kotlinType == typeParameter.defaultType) i else null
|
||||
}
|
||||
for (originalIndex in typeMapping) {
|
||||
// there can be null in case we already captured type parameter in outer class (in case of inner classes)
|
||||
// see test innerClassTypeAliasConstructor.kt
|
||||
val originalTypeParameter = originalTypeParameters.getOrNull(originalIndex) ?: continue
|
||||
val position = DeclaredUpperBoundConstraintPosition(originalTypeParameter)
|
||||
for (upperBound in originalTypeParameter.upperBounds) {
|
||||
freshVariable.addSubtypeConstraint(upperBound, position)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return toFreshVariables
|
||||
@@ -270,7 +301,8 @@ private fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion(
|
||||
if (!argumentIsFunctional) return null
|
||||
|
||||
val originalExpectedType = argument.getExpectedType(candidateParameter.original, callComponents.languageVersionSettings)
|
||||
val convertedTypeByOriginal = callComponents.samConversionTransformer.getFunctionTypeForPossibleSamType(originalExpectedType) ?: return null
|
||||
val convertedTypeByOriginal =
|
||||
callComponents.samConversionTransformer.getFunctionTypeForPossibleSamType(originalExpectedType) ?: return null
|
||||
|
||||
val candidateExpectedType = argument.getExpectedType(candidateParameter, callComponents.languageVersionSettings)
|
||||
val convertedTypeByCandidate = callComponents.samConversionTransformer.getFunctionTypeForPossibleSamType(candidateExpectedType)
|
||||
|
||||
+4
-4
@@ -5,8 +5,8 @@ typealias N<T> = Num<T>
|
||||
typealias N2<T> = N<T>
|
||||
|
||||
val x1 = Num<<!UPPER_BOUND_VIOLATED!>String<!>>("")
|
||||
val x2 = N<<!OI;UPPER_BOUND_VIOLATED!>String<!>>("")
|
||||
val x3 = N2<<!OI;UPPER_BOUND_VIOLATED!>String<!>>("")
|
||||
val x2 = N<<!UPPER_BOUND_VIOLATED!>String<!>>("")
|
||||
val x3 = N2<<!UPPER_BOUND_VIOLATED!>String<!>>("")
|
||||
|
||||
class TColl<T, C : Collection<T>>
|
||||
|
||||
@@ -14,5 +14,5 @@ typealias TC<T, C> = TColl<T, C>
|
||||
typealias TC2<T, C> = TC<T, C>
|
||||
|
||||
val y1 = TColl<Any, <!NI;UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>>()
|
||||
val y2 = TC<Any, <!OI;UPPER_BOUND_VIOLATED!>Any<!>>()
|
||||
val y3 = TC2<Any, <!OI;UPPER_BOUND_VIOLATED!>Any<!>>()
|
||||
val y2 = TC<Any, <!NI;UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>>()
|
||||
val y3 = TC2<Any, <!NI;UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>>()
|
||||
|
||||
+1
-1
@@ -14,4 +14,4 @@ fun test4(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TC2<Number, List<Any
|
||||
val test5 = TC2<Number, Collection<Number>>()
|
||||
val test6 = TC2<Number, Collection<Int>>()
|
||||
val test7 = TC2<Number, List<Int>>()
|
||||
val test8 = TC2<Number, <!OI;UPPER_BOUND_VIOLATED!>List<Any><!>>()
|
||||
val test8 = TC2<Number, <!NI;UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>List<Any><!>>()
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ fun test3(x: NL<Int>) {}
|
||||
fun test4(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>NL<Any><!>) {}
|
||||
|
||||
val test5 = NA<Int>()
|
||||
val test6 = NA<<!OI;UPPER_BOUND_VIOLATED!>Any<!>>()
|
||||
val test6 = NA<<!UPPER_BOUND_VIOLATED!>Any<!>>()
|
||||
val test7 = NL<Int>()
|
||||
val test8 = <!OI;UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>NL<Any>()<!>
|
||||
|
||||
@@ -27,4 +27,4 @@ fun test12(x: TC<Number, <!UPPER_BOUND_VIOLATED!>List<Any><!>>) {}
|
||||
val test13 = TC<Number, Collection<Number>>()
|
||||
val test14 = TC<Number, Collection<Int>>()
|
||||
val test15 = TC<Number, List<Int>>()
|
||||
val test16 = TC<Number, <!OI;UPPER_BOUND_VIOLATED!>List<Any><!>>()
|
||||
val test16 = TC<Number, <!NI;UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>List<Any><!>>()
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package
|
||||
|
||||
public val test1: [ERROR : Type for BOutIn(listOf(), null!!)]
|
||||
public val test2: BInIn<kotlin.Any?> /* = Bound<in kotlin.collections.List<kotlin.Any?>, in kotlin.Any?> */
|
||||
public val test2: BInIn<kotlin.collections.List<kotlin.collections.List<kotlin.Any?>>> /* = Bound<in kotlin.collections.List<kotlin.collections.List<kotlin.collections.List<kotlin.Any?>>>, in kotlin.collections.List<kotlin.collections.List<kotlin.Any?>>> */
|
||||
public fun </*0*/ T> listOf(): kotlin.collections.List<T>
|
||||
|
||||
public final class Bound</*0*/ X, /*1*/ Y : X> {
|
||||
|
||||
Vendored
+1
-1
@@ -5,7 +5,7 @@ class Num<Tn : Number>(val x: Tn)
|
||||
typealias N<T> = Num<T>
|
||||
|
||||
val test0 = N(1)
|
||||
val test1 = <!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>N<!>("1")
|
||||
val test1 = <!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>N<!>(<!NI;TYPE_MISMATCH!>"1"<!>)
|
||||
|
||||
|
||||
class Cons<T>(val head: T, val tail: Cons<T>?)
|
||||
|
||||
+1
-1
@@ -5,4 +5,4 @@ class Cons<T : Number>(val head: T, val tail: Cons<T>?)
|
||||
typealias C<T> = Cons<T>
|
||||
|
||||
val test1 = C(1, C(2, null))
|
||||
val test2 = C(1, <!OI;TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>C<!>("", null))
|
||||
val test2 = C(1, <!NI;TYPE_MISMATCH!><!OI;TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>C<!>(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>""<!>, null)<!>)
|
||||
|
||||
Vendored
+9
-2
@@ -29,7 +29,14 @@ val test3pr = P2<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String, Int, Int><!>(<!OI;CON
|
||||
class Num<T : Number>(val x: T)
|
||||
typealias N<T> = Num<T>
|
||||
|
||||
val testN0 = <!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>N<!>("")
|
||||
val testN0 = <!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>N<!>(<!NI;TYPE_MISMATCH!>""<!>)
|
||||
val testN1 = N<Int>(1)
|
||||
val testN1a = N<<!OI;UPPER_BOUND_VIOLATED!>String<!>>("")
|
||||
val testN1a = N<<!UPPER_BOUND_VIOLATED!>String<!>>("")
|
||||
val testN2 = N<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, Int><!>(1)
|
||||
|
||||
class MyPair<T1 : CharSequence, T2 : Number>(val string: T1, val number: T2)
|
||||
typealias MP<T1> = MyPair<String, T1>
|
||||
|
||||
val testMP0 = MP<Int>("", 1)
|
||||
val testMP1 = <!OI;TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>MP<!>(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>, <!NI;TYPE_MISMATCH!>""<!>)
|
||||
val testMP2 = MP<<!UPPER_BOUND_VIOLATED!>String<!>>("", "")
|
||||
Vendored
+13
@@ -14,11 +14,23 @@ public val test2pra: PR<kotlin.String, kotlin.Int> /* = Pair<kotlin.Int, kotlin.
|
||||
public val test3: P<kotlin.Int, kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
|
||||
public val test3p2: P2<kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
|
||||
public val test3pr: Pair<out kotlin.Any, out kotlin.Any>
|
||||
public val testMP0: MP<kotlin.Int> /* = MyPair<kotlin.String, kotlin.Int> */
|
||||
public val testMP1: MP<kotlin.String> /* = MyPair<kotlin.String, kotlin.String> */
|
||||
public val testMP2: MP<kotlin.String> /* = MyPair<kotlin.String, kotlin.String> */
|
||||
public val testN0: N<kotlin.String> /* = Num<kotlin.String> */
|
||||
public val testN1: N<kotlin.Int> /* = Num<kotlin.Int> */
|
||||
public val testN1a: N<kotlin.String> /* = Num<kotlin.String> */
|
||||
public val testN2: N<kotlin.Int> /* = Num<kotlin.Int> */
|
||||
|
||||
public final class MyPair</*0*/ T1 : kotlin.CharSequence, /*1*/ T2 : kotlin.Number> {
|
||||
public constructor MyPair</*0*/ T1 : kotlin.CharSequence, /*1*/ T2 : kotlin.Number>(/*0*/ string: T1, /*1*/ number: T2)
|
||||
public final val number: T2
|
||||
public final val string: T1
|
||||
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 Num</*0*/ T : kotlin.Number> {
|
||||
public constructor Num</*0*/ T : kotlin.Number>(/*0*/ x: T)
|
||||
public final val x: T
|
||||
@@ -35,6 +47,7 @@ public final class Pair</*0*/ T1, /*1*/ T2> {
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
public typealias MP</*0*/ T1> = MyPair<kotlin.String, T1>
|
||||
public typealias N</*0*/ T> = Num<T>
|
||||
public typealias P</*0*/ T1, /*1*/ T2> = Pair<T1, T2>
|
||||
public typealias P2</*0*/ T> = Pair<T, T>
|
||||
|
||||
Vendored
+13
@@ -14,11 +14,23 @@ public val test2pra: PR<kotlin.String, kotlin.Int> /* = Pair<kotlin.Int, kotlin.
|
||||
public val test3: P<kotlin.Int, kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
|
||||
public val test3p2: P2<kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
|
||||
public val test3pr: P2<kotlin.String> /* = Pair<kotlin.String, kotlin.String> */
|
||||
public val testMP0: MP<kotlin.Int> /* = MyPair<kotlin.String, kotlin.Int> */
|
||||
public val testMP1: [ERROR : Type for MP(1, "")]
|
||||
public val testMP2: MP<kotlin.String> /* = MyPair<kotlin.String, kotlin.String> */
|
||||
public val testN0: [ERROR : Type for N("")]
|
||||
public val testN1: N<kotlin.Int> /* = Num<kotlin.Int> */
|
||||
public val testN1a: N<kotlin.String> /* = Num<kotlin.String> */
|
||||
public val testN2: N<kotlin.Int> /* = Num<kotlin.Int> */
|
||||
|
||||
public final class MyPair</*0*/ T1 : kotlin.CharSequence, /*1*/ T2 : kotlin.Number> {
|
||||
public constructor MyPair</*0*/ T1 : kotlin.CharSequence, /*1*/ T2 : kotlin.Number>(/*0*/ string: T1, /*1*/ number: T2)
|
||||
public final val number: T2
|
||||
public final val string: T1
|
||||
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 Num</*0*/ T : kotlin.Number> {
|
||||
public constructor Num</*0*/ T : kotlin.Number>(/*0*/ x: T)
|
||||
public final val x: T
|
||||
@@ -35,6 +47,7 @@ public final class Pair</*0*/ T1, /*1*/ T2> {
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
public typealias MP</*0*/ T1> = MyPair<kotlin.String, T1>
|
||||
public typealias N</*0*/ T> = Num<T>
|
||||
public typealias P</*0*/ T1, /*1*/ T2> = Pair<T1, T2>
|
||||
public typealias P2</*0*/ T> = Pair<T, T>
|
||||
|
||||
Reference in New Issue
Block a user