diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 2cf6f1207c6..5a60b6be7f8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -116,9 +116,9 @@ public interface Errors { DiagnosticFactory0 GENERIC_THROWABLE_SUBCLASS = DiagnosticFactory0.create(ERROR); DiagnosticFactory1 RECURSIVE_TYPEALIAS_EXPANSION = DiagnosticFactory1.create(ERROR); - DiagnosticFactory3 UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION = + DiagnosticFactory3 UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION = DiagnosticFactory3.create(ERROR); - DiagnosticFactory1 CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION = DiagnosticFactory1.create(ERROR); + DiagnosticFactory1 CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION = DiagnosticFactory1.create(ERROR); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index 462d0dfef66..cc1ab533042 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -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); } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpansionReportStrategy.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpansionReportStrategy.kt index d9db75850aa..12c83c73715 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpansionReportStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpansionReportStrategy.kt @@ -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) {} } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt index 29484d5ad45..20b73479df2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt @@ -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, + 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) + } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt index 2b011fad5f7..b9174bd3ca2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt @@ -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() @@ -565,13 +566,18 @@ class CandidateResolver( inner class ValueArgumentsCheckingResult(val status: ResolutionStatus, val argumentTypes: List) - private fun checkGenericBoundsInAFunctionCall( + private fun CallCandidateResolutionContext<*>.checkGenericBoundsInAFunctionCall( ktTypeArguments: List, typeArguments: List, 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, + 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, + 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 CallCandidateResolutionContext.shouldContinue() = candidateResolveMode == CandidateResolveMode.FULLY || candidateCall.status.possibleTransformToSuccess() diff --git a/compiler/testData/diagnostics/tests/typealias/boundsViolationInDeepTypeAliasExpansion.kt b/compiler/testData/diagnostics/tests/typealias/boundsViolationInDeepTypeAliasExpansion.kt new file mode 100644 index 00000000000..ad38c5b85db --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/boundsViolationInDeepTypeAliasExpansion.kt @@ -0,0 +1,16 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER + +class TColl> + +typealias TC = TColl +typealias TC2 = TC + +fun test1(x: TC2>) {} +fun test2(x: TC2>) {} +fun test3(x: TC2>) {} +fun test4(x: TC2>) {} + +val test5 = TC2>() +val test6 = TC2>() +val test7 = TC2>() +val test8 = TC2List>() diff --git a/compiler/testData/diagnostics/tests/typealias/boundsViolationInDeepTypeAliasExpansion.txt b/compiler/testData/diagnostics/tests/typealias/boundsViolationInDeepTypeAliasExpansion.txt new file mode 100644 index 00000000000..0182f6c987c --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/boundsViolationInDeepTypeAliasExpansion.txt @@ -0,0 +1,19 @@ +package + +public typealias TC = TColl +public typealias TC2 = TC +public val test5: TColl> +public val test6: TColl> +public val test7: TColl> +public val test8: TColl> +public fun test1(/*0*/ x: TC2> [= TColl>]): kotlin.Unit +public fun test2(/*0*/ x: TC2> [= TColl>]): kotlin.Unit +public fun test3(/*0*/ x: TC2> [= TColl>]): kotlin.Unit +public fun test4(/*0*/ x: TC2> [= TColl>]): kotlin.Unit + +public final class TColl> { + public constructor TColl>() + 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 +} diff --git a/compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasExpansion.kt b/compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasExpansion.kt new file mode 100644 index 00000000000..bff8d000d1d --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasExpansion.kt @@ -0,0 +1,29 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER + +class Num +class NumColl> +class TColl> + +typealias NA = Num +typealias NL = NumColl> +typealias TC = TColl + +fun test1(x: NA) {} +fun test2(x: NA<Any>) {} +fun test3(x: NL) {} +fun test4(x: NL) {} + +val test5 = NA() +val test6 = NA<Any>() +val test7 = NL() +val test8 = NL() + +fun test9(x: TC>) {} +fun test10(x: TC>) {} +fun test11(x: TC>) {} +fun test12(x: TCList>) {} + +val test13 = TC>() +val test14 = TC>() +val test15 = TC>() +val test16 = TCList>() diff --git a/compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasExpansion.txt b/compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasExpansion.txt new file mode 100644 index 00000000000..b3832314919 --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasExpansion.txt @@ -0,0 +1,42 @@ +package + +public typealias NA = Num +public typealias NL = NumColl> +public typealias TC = TColl +public val test13: TColl> +public val test14: TColl> +public val test15: TColl> +public val test16: TColl> +public val test5: Num +public val test6: Num +public val test7: NumColl> +public val test8: NumColl> +public fun test1(/*0*/ x: NA [= Num]): kotlin.Unit +public fun test10(/*0*/ x: TC> [= TColl>]): kotlin.Unit +public fun test11(/*0*/ x: TC> [= TColl>]): kotlin.Unit +public fun test12(/*0*/ x: TC> [= TColl>]): kotlin.Unit +public fun test2(/*0*/ x: NA [= Num]): kotlin.Unit +public fun test3(/*0*/ x: NL [= NumColl>]): kotlin.Unit +public fun test4(/*0*/ x: NL [= NumColl>]): kotlin.Unit +public fun test9(/*0*/ x: TC> [= TColl>]): kotlin.Unit + +public final class Num { + public constructor Num() + 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> { + public constructor NumColl>() + 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> { + public constructor TColl>() + 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 +} diff --git a/compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasRHS.kt b/compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasRHS.kt new file mode 100644 index 00000000000..cf871ebee3a --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasRHS.kt @@ -0,0 +1,12 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER + +class TColl> + +typealias TCErr = TCollAny> +typealias TCErr2 = TCErr + +fun testType1(x: TCErr) {} +val testCtor1 = TCErr() + +fun testType2(x: TCErr2) {} +val testCtor2 = TCErr2() diff --git a/compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasRHS.txt b/compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasRHS.txt new file mode 100644 index 00000000000..f0f04412d92 --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/boundsViolationInTypeAliasRHS.txt @@ -0,0 +1,15 @@ +package + +public typealias TCErr = TColl +public typealias TCErr2 = TCErr +public val testCtor1: TColl +public val testCtor2: TColl +public fun testType1(/*0*/ x: TCErr [= TColl]): kotlin.Unit +public fun testType2(/*0*/ x: TCErr2 [= TColl]): kotlin.Unit + +public final class TColl> { + public constructor TColl>() + 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 306e793458c..8bef8f1a576 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -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");