Infer type arguments of type alias constructors.

This commit is contained in:
Dmitry Petrov
2016-11-08 15:38:03 +03:00
parent 9b55ad82a0
commit 03d8aa272b
14 changed files with 265 additions and 18 deletions
@@ -38,10 +38,11 @@ import org.jetbrains.kotlin.resolve.calls.inference.*
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.LOWER_BOUND import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.LOWER_BOUND
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.UPPER_BOUND import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.UPPER_BOUND
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ValidityConstraintForConstituentType
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.getValidityConstraintForConstituentType
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeIntersector import org.jetbrains.kotlin.types.TypeIntersector
@@ -52,6 +53,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.io.PrintWriter import java.io.PrintWriter
import java.io.StringWriter import java.io.StringWriter
import java.lang.AssertionError import java.lang.AssertionError
import java.util.*
object Renderers { object Renderers {
@@ -273,12 +275,20 @@ object Renderers {
val typeParameterDescriptor = inferenceErrorData.descriptor.typeParameters.firstOrNull { val typeParameterDescriptor = inferenceErrorData.descriptor.typeParameters.firstOrNull {
!ConstraintsUtil.checkUpperBoundIsSatisfied(systemWithoutWeakConstraints, it, inferenceErrorData.call, true) !ConstraintsUtil.checkUpperBoundIsSatisfied(systemWithoutWeakConstraints, it, inferenceErrorData.call, true)
} }
if (typeParameterDescriptor == null && status.hasConflictingConstraints()) {
return renderConflictingSubstitutionsInferenceError(inferenceErrorData, result)
}
if (typeParameterDescriptor == null) { if (typeParameterDescriptor == null) {
if (inferenceErrorData.descriptor is TypeAliasConstructorDescriptor) {
renderUpperBoundViolatedInferenceErrorForTypeAliasConstructor(inferenceErrorData, result, systemWithoutWeakConstraints)?.let {
return it
}
}
return if (status.hasConflictingConstraints())
renderConflictingSubstitutionsInferenceError(inferenceErrorData, result)
else {
LOG.error(debugMessage("There is no type parameter with violated upper bound for 'upper bound violated' error", inferenceErrorData)) LOG.error(debugMessage("There is no type parameter with violated upper bound for 'upper bound violated' error", inferenceErrorData))
return result result
}
} }
val typeVariable = systemWithoutWeakConstraints.descriptorToVariable(inferenceErrorData.call.toHandle(), typeParameterDescriptor) val typeVariable = systemWithoutWeakConstraints.descriptorToVariable(inferenceErrorData.call.toHandle(), typeParameterDescriptor)
@@ -322,6 +332,42 @@ object Renderers {
return result return result
} }
private fun renderUpperBoundViolatedInferenceErrorForTypeAliasConstructor(
inferenceErrorData: InferenceErrorData,
result: TabledDescriptorRenderer,
systemWithoutWeakConstraints: ConstraintSystem
): TabledDescriptorRenderer? {
val descriptor = inferenceErrorData.descriptor
if (descriptor !is TypeAliasConstructorDescriptor) {
LOG.error("Type alias constructor descriptor expected: $descriptor")
return result
}
val inferredTypeSubstitutor = systemWithoutWeakConstraints.resultingSubstitutor
for (constraintError in inferenceErrorData.constraintSystem.status.constraintErrors) {
val constraintInfo = constraintError.constraintPosition.getValidityConstraintForConstituentType() ?: continue
if (constraintInfo.typeParameter.variance == Variance.IN_VARIANCE) continue
val violatedUpperBound = inferredTypeSubstitutor.safeSubstitute(constraintInfo.bound, Variance.INVARIANT)
val violatingInferredType = inferredTypeSubstitutor.safeSubstitute(constraintInfo.typeArgument, Variance.INVARIANT)
val context = RenderingContext.of(violatingInferredType, violatedUpperBound)
val typeRenderer = result.typeRenderer
result.text(newText().normal("Type parameter bound for ").strong(constraintInfo.typeParameter.name)
.normal(" in type inferred from type alias expansion for "))
.table(newTable().descriptor(inferenceErrorData.descriptor))
result.text(newText().normal(" is not satisfied: inferred type ").error(typeRenderer.render(violatingInferredType, context))
.normal(" is not a subtype of ").strong(typeRenderer.render(violatedUpperBound, context)))
return result
}
return null
}
@JvmStatic fun renderCannotCaptureTypeParameterError( @JvmStatic fun renderCannotCaptureTypeParameterError(
inferenceErrorData: InferenceErrorData, result: TabledDescriptorRenderer inferenceErrorData: InferenceErrorData, result: TabledDescriptorRenderer
): TabledDescriptorRenderer { ): TabledDescriptorRenderer {
@@ -115,7 +115,7 @@ class CandidateResolver(
if (candidateCall.knownTypeParametersSubstitutor != null) { if (candidateCall.knownTypeParametersSubstitutor != null) {
candidateCall.setResultingSubstitutor(candidateCall.knownTypeParametersSubstitutor!!) candidateCall.setResultingSubstitutor(candidateCall.knownTypeParametersSubstitutor!!)
} }
else if (ktTypeArguments.isNotEmpty() || candidateDescriptor is TypeAliasConstructorDescriptor) { else if (ktTypeArguments.isNotEmpty()) {
// Explicit type arguments passed // Explicit type arguments passed
val typeArguments = ArrayList<KotlinType>() val typeArguments = ArrayList<KotlinType>()
@@ -18,9 +18,8 @@ package org.jetbrains.kotlin.resolve.calls
import org.jetbrains.kotlin.builtins.ReflectionTypes import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.* import org.jetbrains.kotlin.resolve.calls.callResolverUtil.*
@@ -34,8 +33,10 @@ import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
import org.jetbrains.kotlin.resolve.calls.context.ResolutionResultsCache import org.jetbrains.kotlin.resolve.calls.context.ResolutionResultsCache
import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache
import org.jetbrains.kotlin.resolve.calls.inference.* import org.jetbrains.kotlin.resolve.calls.inference.*
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ValidityConstraintForConstituentType
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.TYPE_BOUND_POSITION
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.makeNullableTypeIfSafeReceiver import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.makeNullableTypeIfSafeReceiver
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
@@ -74,6 +75,11 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
} }
} }
if (candidate is TypeAliasConstructorDescriptor) {
val substitutedReturnType = builder.compositeSubstitutor().safeSubstitute(candidate.returnType, Variance.INVARIANT)
addValidityConstraintsForConstituentTypes(builder, substitutedReturnType)
}
// Receiver // Receiver
// Error is already reported if something is missing // Error is already reported if something is missing
val receiverArgument = candidateCall.extensionReceiver val receiverArgument = candidateCall.extensionReceiver
@@ -105,6 +111,34 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
return OTHER_ERROR return OTHER_ERROR
} }
private fun addValidityConstraintsForConstituentTypes(builder: ConstraintSystem.Builder, type: KotlinType) {
val typeConstructor = type.constructor
if (typeConstructor.declarationDescriptor is TypeParameterDescriptor) return
val boundsSubstitutor = TypeSubstitutor.create(type)
type.arguments.forEachIndexed forEachArgument@{ i, typeProjection ->
if (typeProjection.isStarProjection) return@forEachArgument // continue
val typeParameter = typeConstructor.parameters[i]
addValidityConstraintsForTypeArgument(builder, typeProjection, typeParameter, boundsSubstitutor)
}
}
private fun addValidityConstraintsForTypeArgument(
builder: ConstraintSystem.Builder,
typeProjection: TypeProjection,
typeParameter: TypeParameterDescriptor,
boundsSubstitutor: TypeSubstitutor
) {
val typeArgument = typeProjection.type
for (upperBound in typeParameter.upperBounds) {
val substitutedUpperBound = boundsSubstitutor.safeSubstitute(upperBound, Variance.INVARIANT)
val constraintPosition = ValidityConstraintForConstituentType(typeArgument, typeParameter, substitutedUpperBound)
builder.addSubtypeConstraint(typeArgument, substitutedUpperBound, constraintPosition)
}
}
// Creates a substitutor which maps types to their representation in the constraint system. // Creates a substitutor which maps types to their representation in the constraint system.
// In case when some type parameter descriptor is represented by more than one variable in the system, the behavior is undefined. // In case when some type parameter descriptor is represented by more than one variable in the system, the behavior is undefined.
private fun ConstraintSystem.Builder.compositeSubstitutor(): TypeSubstitutor { private fun ConstraintSystem.Builder.compositeSubstitutor(): TypeSubstitutor {
@@ -16,7 +16,9 @@
package org.jetbrains.kotlin.resolve.calls.inference.constraintPosition package org.jetbrains.kotlin.resolve.calls.inference.constraintPosition
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.* import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
import org.jetbrains.kotlin.types.KotlinType
enum class ConstraintPositionKind { enum class ConstraintPositionKind {
RECEIVER_POSITION, RECEIVER_POSITION,
@@ -72,3 +74,21 @@ class CompoundConstraintPosition(vararg positions: ConstraintPosition) : Constra
fun ConstraintPosition.derivedFrom(kind: ConstraintPositionKind): Boolean { fun ConstraintPosition.derivedFrom(kind: ConstraintPositionKind): Boolean {
return if (this !is CompoundConstraintPosition) this.kind == kind else positions.any { it.kind == kind } return if (this !is CompoundConstraintPosition) this.kind == kind else positions.any { it.kind == kind }
} }
class ValidityConstraintForConstituentType(
val typeArgument: KotlinType,
val typeParameter: TypeParameterDescriptor,
val bound: KotlinType
) : ConstraintPosition {
override val kind: ConstraintPositionKind get() = TYPE_BOUND_POSITION
}
fun ConstraintPosition.getValidityConstraintForConstituentType(): ValidityConstraintForConstituentType? =
when (this) {
is ValidityConstraintForConstituentType ->
this
is CompoundConstraintPosition ->
positions.asSequence().map { it.getValidityConstraintForConstituentType() }.firstOrNull { it != null }
else ->
null
}
@@ -0,0 +1,13 @@
class Bound<X, Y : X>(val x: X, val y: Y)
typealias B<X, Y> = Bound<X, Y>
typealias BOutIn<T> = Bound<out List<T>, in T>
typealias BInIn<T> = Bound<in List<T>, in T>
fun <T> listOf(): List<T> = null!!
// Unresolved reference is ok here:
// we can't create a substituted signature for type alias constructor
// since it has 'out' type projection in 'in' position.
val test1 = <!UNRESOLVED_REFERENCE!>BOutIn<!>(<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>listOf<!>(), null!!)
val test2 = BInIn(listOf(), null!!)
@@ -0,0 +1,17 @@
package
public val test1: [ERROR : Type for BOutIn(listOf(), null!!)]
public val test2: Bound<in kotlin.collections.List<kotlin.Nothing>, in kotlin.Nothing>
public fun </*0*/ T> listOf(): kotlin.collections.List<T>
public final class Bound</*0*/ X, /*1*/ Y : X> {
public constructor Bound</*0*/ X, /*1*/ Y : X>(/*0*/ x: X, /*1*/ y: Y)
public final val x: X
public final val y: Y
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 B</*0*/ X, /*1*/ Y> = Bound<X, Y>
public typealias BInIn</*0*/ T> = Bound<in kotlin.collections.List<T>, in T>
public typealias BOutIn</*0*/ T> = Bound<out kotlin.collections.List<T>, in T>
@@ -0,0 +1,27 @@
class Num<Tn : Number>(val x: Tn)
typealias N<T> = Num<T>
class Cons<T>(val head: T, val tail: Cons<T>?)
typealias C<T> = Cons<T>
typealias CC<T> = C<C<T>>
class Pair<X, Y>(val x: X, val y: Y)
typealias PL<T> = Pair<T, List<T>>
class Bound<X, Y : X>(val x: X, val y: Y)
typealias B<X, Y> = Bound<X, Y>
class Foo<T>(val p: Pair<T, T>)
typealias F<T> = Foo<T>
val test0 = N(1)
val test1 = <!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>N<!>("1")
val test2 = <!TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>C<!>(1, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!>)
val test3 = <!TYPE_INFERENCE_INCORPORATION_ERROR!>PL<!>(1, <!NULL_FOR_NONNULL_TYPE!>null<!>)
val test4 = <!TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>CC<!>(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!>)
val test4a = CC(C(1, null), null)
fun testProjections1(x: Pair<in Int, out String>) = <!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>F<!>(x)
fun testProjections2(x: Pair<in Int, out Number>) = <!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>F<!>(x)
fun testProjections3(x: Pair<in Number, out Int>) = <!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>F<!>(x)
fun testProjections4(x: Pair<in Int, in Int>) = <!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>F<!>(x)
@@ -0,0 +1,61 @@
package
public val test0: Num<kotlin.Int>
public val test1: [ERROR : Type for N("1")]
public val test2: Cons<kotlin.Int>
public val test3: Pair<kotlin.Int, kotlin.collections.List<kotlin.Int>>
public val test4: [ERROR : Type for CC(1, 2)]
public val test4a: Cons<Cons<kotlin.Int>>
public fun testProjections1(/*0*/ x: Pair<in kotlin.Int, out kotlin.String>): [ERROR : Error function type]
public fun testProjections2(/*0*/ x: Pair<in kotlin.Int, out kotlin.Number>): [ERROR : Error function type]
public fun testProjections3(/*0*/ x: Pair<in kotlin.Number, out kotlin.Int>): [ERROR : Error function type]
public fun testProjections4(/*0*/ x: Pair<in kotlin.Int, in kotlin.Int>): [ERROR : Error function type]
public final class Bound</*0*/ X, /*1*/ Y : X> {
public constructor Bound</*0*/ X, /*1*/ Y : X>(/*0*/ x: X, /*1*/ y: Y)
public final val x: X
public final val y: Y
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 Cons</*0*/ T> {
public constructor Cons</*0*/ T>(/*0*/ head: T, /*1*/ tail: Cons<T>?)
public final val head: T
public final val tail: Cons<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 Foo</*0*/ T> {
public constructor Foo</*0*/ T>(/*0*/ p: Pair<T, T>)
public final val p: Pair<T, 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 Num</*0*/ Tn : kotlin.Number> {
public constructor Num</*0*/ Tn : kotlin.Number>(/*0*/ x: Tn)
public final val x: Tn
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 Pair</*0*/ X, /*1*/ Y> {
public constructor Pair</*0*/ X, /*1*/ Y>(/*0*/ x: X, /*1*/ y: Y)
public final val x: X
public final val y: Y
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 B</*0*/ X, /*1*/ Y> = Bound<X, Y>
public typealias C</*0*/ T> = Cons<T>
public typealias CC</*0*/ T> = C<C<T>>
public typealias F</*0*/ T> = Foo<T>
public typealias N</*0*/ T> = Num<T>
public typealias PL</*0*/ T> = Pair<T, kotlin.collections.List<T>>
@@ -6,18 +6,18 @@ typealias P2<T> = Pair<T, T>
typealias PR<T1, T2> = Pair<T2, T1> typealias PR<T1, T2> = Pair<T2, T1>
val test0 = <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>P<!>(1, 2) val test0 = P(1, 2)
val test1 = P<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>(1, 2) val test1 = P<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>(1, 2)
val test2 = P<Int, Int>(1, 2) val test2 = P<Int, Int>(1, 2)
val test3 = P<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, Int, Int><!>(1, 2) val test3 = P<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, Int, Int><!>(1, 2)
val test0p2 = <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>P2<!>(1, 1) val test0p2 = P2(1, 1)
val test0p2a = <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>P2<!>(1, "") val test0p2a = P2(1, "")
val test1p2 = P2<Int>(1, 1) val test1p2 = P2<Int>(1, 1)
val test2p2 = P2<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, Int><!>(1, 1) val test2p2 = P2<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, Int><!>(1, 1)
val test3p2 = P2<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, Int, Int><!>(1, 1) val test3p2 = P2<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, Int, Int><!>(1, 1)
val test0pr = <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>PR<!>(1, "") val test0pr = PR(1, "")
val test1pr = PR<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>(1, <!TYPE_MISMATCH!>""<!>) val test1pr = PR<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>(1, <!TYPE_MISMATCH!>""<!>)
val test2pr = PR<Int, String>(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>, <!TYPE_MISMATCH!>""<!>) val test2pr = PR<Int, String>(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>, <!TYPE_MISMATCH!>""<!>)
val test2pra = PR<String, Int>(1, "") val test2pra = PR<String, Int>(1, "")
@@ -26,7 +26,7 @@ val test3pr = P2<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String, Int, Int><!>(<!CONSTA
class Num<T : Number>(val x: T) class Num<T : Number>(val x: T)
typealias N<T> = Num<T> typealias N<T> = Num<T>
val testN0 = <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>N<!>("") val testN0 = <!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>N<!>("")
val testN1 = N<Int>(1) val testN1 = N<Int>(1)
val testN1a = N<<!UPPER_BOUND_VIOLATED!>String<!>>("") val testN1a = N<<!UPPER_BOUND_VIOLATED!>String<!>>("")
val testN2 = N<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, Int><!>(1) val testN2 = N<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, Int><!>(1)
@@ -14,7 +14,7 @@ public val test2pra: Pair<kotlin.Int, kotlin.String>
public val test3: Pair<kotlin.Int, kotlin.Int> public val test3: Pair<kotlin.Int, kotlin.Int>
public val test3p2: Pair<kotlin.Int, kotlin.Int> public val test3p2: Pair<kotlin.Int, kotlin.Int>
public val test3pr: Pair<kotlin.String, kotlin.String> public val test3pr: Pair<kotlin.String, kotlin.String>
public val testN0: Num<kotlin.String> public val testN0: [ERROR : Type for N("")]
public val testN1: Num<kotlin.Int> public val testN1: Num<kotlin.Int>
public val testN1a: Num<kotlin.String> public val testN1a: Num<kotlin.String>
public val testN2: Num<kotlin.Int> public val testN2: Num<kotlin.Int>
@@ -21027,12 +21027,24 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("typeAliasConstructorCrazyProjections.kt")
public void testTypeAliasConstructorCrazyProjections() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typeAliasConstructorCrazyProjections.kt");
doTest(fileName);
}
@TestMetadata("typeAliasConstructorInSuperCall.kt") @TestMetadata("typeAliasConstructorInSuperCall.kt")
public void testTypeAliasConstructorInSuperCall() throws Exception { public void testTypeAliasConstructorInSuperCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typeAliasConstructorInSuperCall.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typeAliasConstructorInSuperCall.kt");
doTest(fileName); doTest(fileName);
} }
@TestMetadata("typeAliasConstructorTypeArgumentsInference.kt")
public void testTypeAliasConstructorTypeArgumentsInference() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typeAliasConstructorTypeArgumentsInference.kt");
doTest(fileName);
}
@TestMetadata("typeAliasConstructorWrongClass.kt") @TestMetadata("typeAliasConstructorWrongClass.kt")
public void testTypeAliasConstructorWrongClass() throws Exception { public void testTypeAliasConstructorWrongClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.kt");
@@ -0,0 +1,8 @@
// !DIAGNOSTICS_NUMBER: 1
// !DIAGNOSTICS: TYPE_INFERENCE_UPPER_BOUND_VIOLATED
// !MESSAGE_TYPE: TEXT
class Num<Tn : Number>(val x: Tn)
typealias N<T> = Num<T>
val test = N("")
@@ -0,0 +1,3 @@
<!-- upperBoundViolatedInTypeAliasConstructorCall1 -->
Type parameter bound for Tn in type inferred from type alias expansion for fun <T> <init>(x: T): Num<T>
is not satisfied: inferred type T is not a subtype of Number
@@ -310,4 +310,10 @@ public class DiagnosticMessageTestGenerated extends AbstractDiagnosticMessageTes
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/diagnosticMessage/upperBoundViolated.kt"); String fileName = KotlinTestUtils.navigationMetadata("idea/testData/diagnosticMessage/upperBoundViolated.kt");
doTest(fileName); doTest(fileName);
} }
@TestMetadata("upperBoundViolatedInTypeAliasConstructorCall.kt")
public void testUpperBoundViolatedInTypeAliasConstructorCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/diagnosticMessage/upperBoundViolatedInTypeAliasConstructorCall.kt");
doTest(fileName);
}
} }