KT-11588 Type aliases

Diagnostics for type arguments substitution in type alias expansion
(initial implementation; TODO: refactor).
This commit is contained in:
Dmitry Petrov
2016-05-26 10:10:46 +03:00
parent 9cf8ef287e
commit e979300579
12 changed files with 275 additions and 18 deletions
@@ -116,9 +116,9 @@ public interface Errors {
DiagnosticFactory0<KtTypeParameterList> GENERIC_THROWABLE_SUBCLASS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<KtUserType, ClassifierDescriptor> RECURSIVE_TYPEALIAS_EXPANSION = DiagnosticFactory1.create(ERROR);
DiagnosticFactory3<KtUserType, KotlinType, KotlinType, ClassifierDescriptor> UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION =
DiagnosticFactory3<KtElement, KotlinType, KotlinType, ClassifierDescriptor> UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION =
DiagnosticFactory3.create(ERROR);
DiagnosticFactory1<KtUserType, KotlinType> CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<KtElement, KotlinType> CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION = DiagnosticFactory1.create(ERROR);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1170,6 +1170,7 @@ public class DescriptorResolver {
public static void checkBoundsInTypeAlias(
@NotNull TypeAliasExpansionReportStrategy reportStrategy,
@NotNull KotlinType unsubstitutedArgument,
@NotNull KotlinType typeArgument,
@NotNull TypeParameterDescriptor typeParameterDescriptor,
@NotNull TypeSubstitutor substitutor
@@ -1177,7 +1178,7 @@ public class DescriptorResolver {
for (KotlinType bound : typeParameterDescriptor.getUpperBounds()) {
KotlinType substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT);
if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(typeArgument, substitutedBound)) {
reportStrategy.boundsViolationInSubstitution(substitutedBound, typeArgument, typeParameterDescriptor);
reportStrategy.boundsViolationInSubstitution(substitutedBound, unsubstitutedArgument, typeArgument, typeParameterDescriptor);
}
}
}
@@ -24,12 +24,12 @@ interface TypeAliasExpansionReportStrategy {
fun wrongNumberOfTypeArguments(typeAlias: TypeAliasDescriptor, numberOfParameters: Int)
fun conflictingProjection(typeAlias: TypeAliasDescriptor, typeParameter: TypeParameterDescriptor?, expandingType: KotlinType)
fun recursiveTypeAlias(typeAlias: TypeAliasDescriptor)
fun boundsViolationInSubstitution(bound: KotlinType, argument: KotlinType, typeParameter: TypeParameterDescriptor)
fun boundsViolationInSubstitution(bound: KotlinType, unsubstitutedArgument: KotlinType, argument: KotlinType, typeParameter: TypeParameterDescriptor)
object DEFAULT : TypeAliasExpansionReportStrategy {
override fun wrongNumberOfTypeArguments(typeAlias: TypeAliasDescriptor, numberOfParameters: Int) {}
override fun conflictingProjection(typeAlias: TypeAliasDescriptor, typeParameter: TypeParameterDescriptor?, expandingType: KotlinType) {}
override fun recursiveTypeAlias(typeAlias: TypeAliasDescriptor) {}
override fun boundsViolationInSubstitution(bound: KotlinType, argument: KotlinType, typeParameter: TypeParameterDescriptor) {}
override fun boundsViolationInSubstitution(bound: KotlinType, unsubstitutedArgument: KotlinType, argument: KotlinType, typeParameter: TypeParameterDescriptor) {}
}
}
@@ -396,6 +396,9 @@ class TypeResolver(
for (i in parameters.indices) {
val parameter = parameters[i]
val argument = arguments[i].type
if (argument.dependsOnTypeAliasParameters()) continue
val typeReference = collectedArgumentAsTypeProjections.getOrNull(i)?.typeReference
if (typeReference != null) {
@@ -411,6 +414,12 @@ class TypeResolver(
return type(resultingType)
}
private fun KotlinType.dependsOnTypeAliasParameters(): Boolean =
TypeUtils.contains(this) { type ->
val constructorDeclaration = type.constructor.declarationDescriptor
constructorDeclaration is TypeParameterDescriptor && constructorDeclaration.containingDeclaration is TypeAliasDescriptor
}
private fun resolveTypeForTypeAlias(
c: TypeResolutionContext,
annotations: Annotations,
@@ -487,8 +496,16 @@ class TypeResolver(
trace.report(RECURSIVE_TYPEALIAS_EXPANSION.on(type, typeAlias))
}
override fun boundsViolationInSubstitution(bound: KotlinType, argument: KotlinType, typeParameter: TypeParameterDescriptor) {
TODO("boundsViolationInSubstitution")
override fun boundsViolationInSubstitution(bound: KotlinType, unsubstitutedArgument: KotlinType, argument: KotlinType, typeParameter: TypeParameterDescriptor) {
val descriptorForUnsubstitutedArgument = unsubstitutedArgument.constructor.declarationDescriptor
val argumentElement = mappedArguments[descriptorForUnsubstitutedArgument]
val argumentTypeReferenceElement = argumentElement?.typeReference
if (argumentTypeReferenceElement != null) {
trace.report(UPPER_BOUND_VIOLATED.on(argumentTypeReferenceElement, bound, argument))
}
else {
trace.report(UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION.on(type, bound, argument, typeParameter))
}
}
}
@@ -631,25 +648,28 @@ class TypeResolver(
expandTypeProjectionForTypeAlias(c, originalArgument, typeAliasExpansion, typeConstructor.parameters[i], reportStrategy, recursionDepth + 1)
}
checkTypeArgumentsSubstitutionInTypeAliasExpansion(type, substitutedArguments, reportStrategy)
val substitutedType = type.replace(newArguments = substitutedArguments)
checkTypeArgumentsSubstitutionInTypeAliasExpansion(type, substitutedType, reportStrategy)
return TypeProjectionImpl(originalProjection.projectionKind, substitutedType)
}
}
}
private fun checkTypeArgumentsSubstitutionInTypeAliasExpansion(
type: KotlinType,
substitutedArguments: List<TypeProjection>,
unsubstitutedType: KotlinType,
substitutedType: KotlinType,
reportStrategy: TypeAliasExpansionReportStrategy
) {
val typeSubstitutor = TypeSubstitutor.create(type)
val typeSubstitutor = TypeSubstitutor.create(substitutedType)
substitutedArguments.forEachIndexed { i, substitutedArgument ->
val typeParameter = type.constructor.parameters[i]
DescriptorResolver.checkBoundsInTypeAlias(reportStrategy, substitutedArgument.type, typeParameter, typeSubstitutor)
substitutedType.arguments.forEachIndexed { i, substitutedArgument ->
if (!substitutedArgument.type.dependsOnTypeAliasParameters()) {
val unsubstitutedArgument = unsubstitutedType.arguments[i]
val typeParameter = unsubstitutedType.constructor.parameters[i]
DescriptorResolver.checkBoundsInTypeAlias(reportStrategy, unsubstitutedArgument.type, substitutedArgument.type, typeParameter, typeSubstitutor)
}
}
}
@@ -21,8 +21,9 @@ import com.google.common.collect.Sets
import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.Errors.SUPER_CANT_BE_EXTENSION_RECEIVER
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.*
@@ -114,7 +115,7 @@ class CandidateResolver(
if (candidateCall.knownTypeParametersSubstitutor != null) {
candidateCall.setResultingSubstitutor(candidateCall.knownTypeParametersSubstitutor!!)
}
else if (!ktTypeArguments.isEmpty()) {
else if (ktTypeArguments.isNotEmpty() || candidateDescriptor is TypeAliasConstructorDescriptor) {
// Explicit type arguments passed
val typeArguments = ArrayList<KotlinType>()
@@ -565,13 +566,18 @@ class CandidateResolver(
inner class ValueArgumentsCheckingResult(val status: ResolutionStatus, val argumentTypes: List<KotlinType>)
private fun checkGenericBoundsInAFunctionCall(
private fun CallCandidateResolutionContext<*>.checkGenericBoundsInAFunctionCall(
ktTypeArguments: List<KtTypeProjection>,
typeArguments: List<KotlinType>,
functionDescriptor: CallableDescriptor,
substitutor: TypeSubstitutor,
trace: BindingTrace
) {
if (functionDescriptor is TypeAliasConstructorDescriptor) {
checkGenericBoundsInTypeAliasConstructorCall(ktTypeArguments, functionDescriptor, substitutor, trace)
return
}
val typeParameters = functionDescriptor.typeParameters
for (i in 0..Math.min(typeParameters.size, ktTypeArguments.size) - 1) {
val typeParameterDescriptor = typeParameters[i]
@@ -583,6 +589,85 @@ class CandidateResolver(
}
}
private class TypeAliasSingleStepExpansionReportStrategy(
private val callElement: KtElement,
typeAlias: TypeAliasDescriptor,
ktTypeArguments: List<KtTypeProjection>,
private val trace: BindingTrace
) : TypeAliasExpansionReportStrategy {
private val argumentsMapping = typeAlias.declaredTypeParameters.zip(ktTypeArguments).toMap()
override fun wrongNumberOfTypeArguments(typeAlias: TypeAliasDescriptor, numberOfParameters: Int) {
}
override fun conflictingProjection(typeAlias: TypeAliasDescriptor, typeParameter: TypeParameterDescriptor?, expandingType: KotlinType) {
// No projections in type alias constructor arguments - can't happen
}
override fun recursiveTypeAlias(typeAlias: TypeAliasDescriptor) {}
override fun boundsViolationInSubstitution(bound: KotlinType, unsubstitutedArgument: KotlinType, argument: KotlinType, typeParameter: TypeParameterDescriptor) {
val descriptorForUnsubstitutedArgument = unsubstitutedArgument.constructor.declarationDescriptor
val argumentElement = argumentsMapping[descriptorForUnsubstitutedArgument]
val argumentTypeReferenceElement = argumentElement?.typeReference
if (argumentTypeReferenceElement != null) {
trace.report(UPPER_BOUND_VIOLATED.on(argumentTypeReferenceElement, bound, argument))
}
else {
trace.report(UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION.on(callElement, bound, argument, typeParameter))
}
}
}
private fun CallCandidateResolutionContext<*>.checkGenericBoundsInTypeAliasConstructorCall(
ktTypeArguments: List<KtTypeProjection>,
typeAliasConstructorDescriptor: TypeAliasConstructorDescriptor,
typeAliasParametersSubstitutor: TypeSubstitutor,
trace: BindingTrace
) {
val substitutedType = typeAliasParametersSubstitutor.substitute(typeAliasConstructorDescriptor.returnType, Variance.INVARIANT)!!
val boundsSubstitutor = TypeSubstitutor.create(substitutedType)
val typeAliasDescriptor = typeAliasConstructorDescriptor.typeAliasDescriptor
val unsubstitutedType = typeAliasDescriptor.expandedType
if (unsubstitutedType.isError) return
val reportStrategy = TypeAliasSingleStepExpansionReportStrategy(call.callElement, typeAliasDescriptor, ktTypeArguments, trace)
// TODO refactor TypeResolver
// - perform full type alias expansion
// - provide type alias expansion stack in diagnostics
checkTypeInTypeAliasSubstitutionRec(reportStrategy, unsubstitutedType, typeAliasParametersSubstitutor, boundsSubstitutor)
}
private fun checkTypeInTypeAliasSubstitutionRec(
reportStrategy: TypeAliasExpansionReportStrategy,
unsubstitutedType: KotlinType,
typeAliasParametersSubstitutor: TypeSubstitutor,
boundsSubstitutor: TypeSubstitutor
) {
// TODO refactor TypeResolver
val typeParameters = unsubstitutedType.constructor.parameters
// TODO do not perform substitution for type arguments multiple times
val substitutedTypeArguments = typeAliasParametersSubstitutor.safeSubstitute(unsubstitutedType, Variance.INVARIANT).arguments
for (i in 0 ..Math.min(typeParameters.size, substitutedTypeArguments.size) - 1) {
val substitutedTypeProjection = substitutedTypeArguments[i]
if (substitutedTypeProjection.isStarProjection) continue
val typeParameter = typeParameters[i]
val substitutedTypeArgument = substitutedTypeProjection.type
val unsubstitutedTypeArgument = unsubstitutedType.arguments[i].type
DescriptorResolver.checkBoundsInTypeAlias(reportStrategy, unsubstitutedTypeArgument, substitutedTypeArgument, typeParameter, boundsSubstitutor)
checkTypeInTypeAliasSubstitutionRec(reportStrategy, unsubstitutedTypeArgument, typeAliasParametersSubstitutor, boundsSubstitutor)
}
}
private fun <D : CallableDescriptor> CallCandidateResolutionContext<D>.shouldContinue() =
candidateResolveMode == CandidateResolveMode.FULLY || candidateCall.status.possibleTransformToSuccess()
@@ -0,0 +1,16 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
class TColl<T, C : Collection<T>>
typealias TC<T1, T2> = TColl<T1, T2>
typealias TC2<T1, T2> = TC<T1, T2>
fun test1(x: TC2<Number, Collection<Number>>) {}
fun test2(x: TC2<Number, Collection<Int>>) {}
fun test3(x: TC2<Number, List<Int>>) {}
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, <!UPPER_BOUND_VIOLATED!>List<Any><!>>()
@@ -0,0 +1,19 @@
package
public typealias TC</*0*/ T1, /*1*/ T2> = TColl<T1, T2>
public typealias TC2</*0*/ T1, /*1*/ T2> = TC<T1, T2>
public val test5: TColl<kotlin.Number, kotlin.collections.Collection<kotlin.Number>>
public val test6: TColl<kotlin.Number, kotlin.collections.Collection<kotlin.Int>>
public val test7: TColl<kotlin.Number, kotlin.collections.List<kotlin.Int>>
public val test8: TColl<kotlin.Number, kotlin.collections.List<kotlin.Any>>
public fun test1(/*0*/ x: TC2<kotlin.Number, kotlin.collections.Collection<kotlin.Number>> [= TColl<kotlin.Number, kotlin.collections.Collection<kotlin.Number>>]): kotlin.Unit
public fun test2(/*0*/ x: TC2<kotlin.Number, kotlin.collections.Collection<kotlin.Int>> [= TColl<kotlin.Number, kotlin.collections.Collection<kotlin.Int>>]): kotlin.Unit
public fun test3(/*0*/ x: TC2<kotlin.Number, kotlin.collections.List<kotlin.Int>> [= TColl<kotlin.Number, kotlin.collections.List<kotlin.Int>>]): kotlin.Unit
public fun test4(/*0*/ x: TC2<kotlin.Number, kotlin.collections.List<kotlin.Any>> [= TColl<kotlin.Number, kotlin.collections.List<kotlin.Any>>]): kotlin.Unit
public final class TColl</*0*/ T, /*1*/ C : kotlin.collections.Collection<T>> {
public constructor TColl</*0*/ T, /*1*/ C : kotlin.collections.Collection<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,29 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
class Num<T : Number>
class NumColl<T : Collection<Number>>
class TColl<T, C : Collection<T>>
typealias NA<T> = Num<T>
typealias NL<T> = NumColl<List<T>>
typealias TC<T1, T2> = TColl<T1, T2>
fun test1(x: NA<Int>) {}
fun test2(x: NA<<!UPPER_BOUND_VIOLATED!>Any<!>>) {}
fun test3(x: NL<Int>) {}
fun test4(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>NL<Any><!>) {}
val test5 = NA<Int>()
val test6 = NA<<!UPPER_BOUND_VIOLATED!>Any<!>>()
val test7 = NL<Int>()
val test8 = <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>NL<Any>()<!>
fun test9(x: TC<Number, Collection<Number>>) {}
fun test10(x: TC<Number, Collection<Int>>) {}
fun test11(x: TC<Number, List<Int>>) {}
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, <!UPPER_BOUND_VIOLATED!>List<Any><!>>()
@@ -0,0 +1,42 @@
package
public typealias NA</*0*/ T> = Num<T>
public typealias NL</*0*/ T> = NumColl<kotlin.collections.List<T>>
public typealias TC</*0*/ T1, /*1*/ T2> = TColl<T1, T2>
public val test13: TColl<kotlin.Number, kotlin.collections.Collection<kotlin.Number>>
public val test14: TColl<kotlin.Number, kotlin.collections.Collection<kotlin.Int>>
public val test15: TColl<kotlin.Number, kotlin.collections.List<kotlin.Int>>
public val test16: TColl<kotlin.Number, kotlin.collections.List<kotlin.Any>>
public val test5: Num<kotlin.Int>
public val test6: Num<kotlin.Any>
public val test7: NumColl<kotlin.collections.List<kotlin.Int>>
public val test8: NumColl<kotlin.collections.List<kotlin.Any>>
public fun test1(/*0*/ x: NA<kotlin.Int> [= Num<kotlin.Int>]): kotlin.Unit
public fun test10(/*0*/ x: TC<kotlin.Number, kotlin.collections.Collection<kotlin.Int>> [= TColl<kotlin.Number, kotlin.collections.Collection<kotlin.Int>>]): kotlin.Unit
public fun test11(/*0*/ x: TC<kotlin.Number, kotlin.collections.List<kotlin.Int>> [= TColl<kotlin.Number, kotlin.collections.List<kotlin.Int>>]): kotlin.Unit
public fun test12(/*0*/ x: TC<kotlin.Number, kotlin.collections.List<kotlin.Any>> [= TColl<kotlin.Number, kotlin.collections.List<kotlin.Any>>]): kotlin.Unit
public fun test2(/*0*/ x: NA<kotlin.Any> [= Num<kotlin.Any>]): kotlin.Unit
public fun test3(/*0*/ x: NL<kotlin.Int> [= NumColl<kotlin.collections.List<out kotlin.Int>>]): kotlin.Unit
public fun test4(/*0*/ x: NL<kotlin.Any> [= NumColl<kotlin.collections.List<out kotlin.Any>>]): kotlin.Unit
public fun test9(/*0*/ x: TC<kotlin.Number, kotlin.collections.Collection<kotlin.Number>> [= TColl<kotlin.Number, kotlin.collections.Collection<kotlin.Number>>]): kotlin.Unit
public final class Num</*0*/ T : kotlin.Number> {
public constructor Num</*0*/ T : kotlin.Number>()
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 NumColl</*0*/ T : kotlin.collections.Collection<kotlin.Number>> {
public constructor NumColl</*0*/ T : kotlin.collections.Collection<kotlin.Number>>()
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 TColl</*0*/ T, /*1*/ C : kotlin.collections.Collection<T>> {
public constructor TColl</*0*/ T, /*1*/ C : kotlin.collections.Collection<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,12 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
class TColl<T, C : Collection<T>>
typealias TCErr = TColl<String, <!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>>
typealias TCErr2 = <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TCErr<!>
fun testType1(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TCErr<!>) {}
val testCtor1 = <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TCErr()<!>
fun testType2(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TCErr2<!>) {}
val testCtor2 = <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TCErr2()<!>
@@ -0,0 +1,15 @@
package
public typealias TCErr = TColl<kotlin.String, kotlin.Any>
public typealias TCErr2 = TCErr
public val testCtor1: TColl<kotlin.String, kotlin.Any>
public val testCtor2: TColl<kotlin.String, kotlin.Any>
public fun testType1(/*0*/ x: TCErr [= TColl<kotlin.String, kotlin.Any>]): kotlin.Unit
public fun testType2(/*0*/ x: TCErr2 [= TColl<kotlin.String, kotlin.Any>]): kotlin.Unit
public final class TColl</*0*/ T, /*1*/ C : kotlin.collections.Collection<T>> {
public constructor TColl</*0*/ T, /*1*/ C : kotlin.collections.Collection<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
}
@@ -19131,6 +19131,24 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/typealias"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("boundsViolationInDeepTypeAliasExpansion.kt")
public void testBoundsViolationInDeepTypeAliasExpansion() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/boundsViolationInDeepTypeAliasExpansion.kt");
doTest(fileName);
}
@TestMetadata("boundsViolationInTypeAliasExpansion.kt")
public void testBoundsViolationInTypeAliasExpansion() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasExpansion.kt");
doTest(fileName);
}
@TestMetadata("boundsViolationInTypeAliasRHS.kt")
public void testBoundsViolationInTypeAliasRHS() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasRHS.kt");
doTest(fileName);
}
@TestMetadata("genericTypeAliasConstructor.kt")
public void testGenericTypeAliasConstructor() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/genericTypeAliasConstructor.kt");