diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 02c499ad58c..44bb6ba03df 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -118,6 +118,8 @@ public interface Errors { DiagnosticFactory1 REDUNDANT_PROJECTION = DiagnosticFactory1.create(WARNING, VARIANCE_IN_PROJECTION); DiagnosticFactory1 TYPE_VARIANCE_CONFLICT = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); + DiagnosticFactory1 TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE = + DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); DiagnosticFactory0 FINITE_BOUNDS_VIOLATION = DiagnosticFactory0.create(ERROR); DiagnosticFactory1 FINITE_BOUNDS_VIOLATION_IN_JAVA = DiagnosticFactory1.create(WARNING); DiagnosticFactory0 EXPANSIVE_INHERITANCE = DiagnosticFactory0.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index a1b8b45c2d4..2c86e2361f6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -546,21 +546,25 @@ public class DefaultErrorMessages { MAP.put(MISPLACED_TYPE_PARAMETER_CONSTRAINTS, "If a type parameter has multiple constraints, they all need to be placed in the 'where' clause"); + MultiRenderer varianceConflictDataRenderer = new MultiRenderer() { + @NotNull + @Override + public String[] render(@NotNull VarianceConflictDiagnosticData data) { + RenderingContext context = + of(data.getTypeParameter(), data.getTypeParameter().getVariance(), data.getOccurrencePosition(), + data.getContainingType()); + return new String[] { + NAME.render(data.getTypeParameter(), context), + RENDER_POSITION_VARIANCE.render(data.getTypeParameter().getVariance(), context), + RENDER_POSITION_VARIANCE.render(data.getOccurrencePosition(), context), + RENDER_TYPE.render(data.getContainingType(), context) + }; + } + }; MAP.put(TYPE_VARIANCE_CONFLICT, "Type parameter {0} is declared as ''{1}'' but occurs in ''{2}'' position in type {3}", - new MultiRenderer() { - @NotNull - @Override - public String[] render(@NotNull VarianceConflictDiagnosticData data) { - RenderingContext context = - of(data.getTypeParameter(), data.getTypeParameter().getVariance(), data.getOccurrencePosition(), data.getContainingType()); - return new String[] { - NAME.render(data.getTypeParameter(), context), - RENDER_POSITION_VARIANCE.render(data.getTypeParameter().getVariance(), context), - RENDER_POSITION_VARIANCE.render(data.getOccurrencePosition(), context), - RENDER_TYPE.render(data.getContainingType(), context) - }; - } - }); + varianceConflictDataRenderer); + MAP.put(TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE, "Type parameter {0} is declared as ''{1}'' but occurs in ''{2}'' position in abbreviated type {3}", + varianceConflictDataRenderer); MAP.put(FINITE_BOUNDS_VIOLATION, "This type parameter violates the Finite Bound Restriction"); MAP.put(FINITE_BOUNDS_VIOLATION_IN_JAVA, "Violation of Finite Bound Restriction for {0}", STRING); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpander.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpander.kt index c7a30d430f4..653d4c8098a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpander.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpander.kt @@ -18,9 +18,7 @@ package org.jetbrains.kotlin.resolve import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor -import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.* diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeBinding.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeBinding.kt index f0f0161bac3..fa7bb60c037 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeBinding.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeBinding.kt @@ -28,20 +28,27 @@ import org.jetbrains.kotlin.types.* interface TypeBinding : TypeHolder> { val psiElement: P + val isInAbbreviation: Boolean override val arguments: List?> } interface TypeArgumentBinding : TypeHolderArgument> fun KtTypeReference.createTypeBinding(trace: BindingContext): TypeBinding? { - val jetType = trace[BindingContext.TYPE, this] + val type = trace[BindingContext.TYPE, this] val psiElement = typeElement - if (jetType == null || psiElement == null) { - return null - } - else { - return ExplicitTypeBinding(trace, psiElement, jetType) - } + return if (type == null || psiElement == null) + null + else + createTypeBindingFromPsi(trace, psiElement, type) +} + +private fun createTypeBindingFromPsi(trace: BindingContext, psiElement: KtTypeElement, type: KotlinType): TypeBinding { + val abbreviatedType = type.getAbbreviatedType() + return if (abbreviatedType != null) + AbbreviatedTypeBinding(type, psiElement) + else + ExplicitTypeBinding(trace, psiElement, type) } fun KtCallableDeclaration.createTypeBindingForReturnType(trace: BindingContext): TypeBinding? { @@ -65,30 +72,30 @@ private class ExplicitTypeBinding( override val psiElement: KtTypeElement, override val type: KotlinType ) : TypeBinding { + override val isInAbbreviation: Boolean get() = false override val arguments: List?> get() { val psiTypeArguments = psiElement.typeArgumentsAsTypes + assert(type.getAbbreviatedType() == null) { "Non-abbreviated type expected: $type" } val isErrorBinding = run { val sizeIsEqual = psiTypeArguments.size == type.arguments.size && psiTypeArguments.size == type.constructor.parameters.size type.isError || !sizeIsEqual } - return psiTypeArguments.indices.map { index: Int -> - // todo fix for List<*> - val jetTypeReference = psiTypeArguments[index] - val jetTypeElement = jetTypeReference?.typeElement - if (jetTypeElement == null) return@map null + return psiTypeArguments.indices.map { index: Int -> + // todo fix for List<*> + val jetTypeReference = psiTypeArguments[index] + val jetTypeElement = jetTypeReference?.typeElement ?: return@map null - if (isErrorBinding) { - val nextJetType = trace[BindingContext.TYPE, jetTypeReference] - if (nextJetType == null) return@map null + if (isErrorBinding) { + val nextJetType = trace[BindingContext.TYPE, jetTypeReference] ?: return@map null return@map TypeArgumentBindingImpl( TypeProjectionImpl(nextJetType), null, - ExplicitTypeBinding(trace, jetTypeElement, nextJetType) + createTypeBindingFromPsi(trace, jetTypeElement, nextJetType) ) } @@ -96,17 +103,34 @@ private class ExplicitTypeBinding( return@map TypeArgumentBindingImpl( typeProjection, type.constructor.parameters[index], - ExplicitTypeBinding(trace, jetTypeElement, typeProjection.type) + createTypeBindingFromPsi(trace, jetTypeElement, typeProjection.type) ) } } } +private class AbbreviatedTypeBinding( + override val type: KotlinType, + override val psiElement: KtTypeElement +): TypeBinding { + override val isInAbbreviation: Boolean get() = true + + override val arguments: List?> + get() = type.arguments.mapIndexed { index, argument -> + TypeArgumentBindingImpl( + argument, + type.constructor.parameters[index], + AbbreviatedTypeBinding(argument.type, psiElement) + ) + } +} + private class NoTypeElementBinding( private val trace: BindingContext, override val psiElement: P, override val type: KotlinType ): TypeBinding

{ + override val isInAbbreviation: Boolean get() = false override val arguments: List?> get() { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VarianceChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VarianceChecker.kt index 31fd5bc68cb..8472e86a8ad 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VarianceChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VarianceChecker.kt @@ -16,30 +16,23 @@ package org.jetbrains.kotlin.resolve -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.diagnostics.Errors -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor -import org.jetbrains.kotlin.types.Variance -import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure.EnrichedProjectionKind.* -import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure.* -import org.jetbrains.kotlin.descriptors.Visibilities -import org.jetbrains.kotlin.resolve.typeBinding.TypeBinding import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.PropertyAccessorDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl +import org.jetbrains.kotlin.diagnostics.DiagnosticSink +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.source.getPsi +import org.jetbrains.kotlin.resolve.typeBinding.TypeBinding import org.jetbrains.kotlin.resolve.typeBinding.createTypeBinding import org.jetbrains.kotlin.resolve.typeBinding.createTypeBindingForReturnType -import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance.* -import org.jetbrains.kotlin.diagnostics.DiagnosticSink -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor -import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl -import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl -import org.jetbrains.kotlin.descriptors.impl.PropertyAccessorDescriptorImpl -import org.jetbrains.kotlin.resolve.source.getPsi -import org.jetbrains.kotlin.descriptors.VariableDescriptor -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.types.checkTypePosition +import org.jetbrains.kotlin.types.getAbbreviatedType class ManualVariance(val descriptor: TypeParameterDescriptor, val variance: Variance) @@ -167,12 +160,9 @@ class VarianceCheckerCore( checkTypePosition( position, { typeParameterDescriptor, typeBinding, errorPosition -> - diagnosticSink.report( - Errors.TYPE_VARIANCE_CONFLICT.on( - typeBinding.psiElement, - VarianceConflictDiagnosticData(containingType, typeParameterDescriptor, errorPosition) - ) - ) + val varianceConflictDiagnosticData = VarianceConflictDiagnosticData(containingType, typeParameterDescriptor, errorPosition) + val diagnostic = if (typeBinding.isInAbbreviation) Errors.TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE else Errors.TYPE_VARIANCE_CONFLICT + diagnosticSink.report(diagnostic.on(typeBinding.psiElement, varianceConflictDiagnosticData)) }, customVariance = { it.varianceWithManual() } ) diff --git a/compiler/testData/diagnostics/tests/typealias/kt14498.kt b/compiler/testData/diagnostics/tests/typealias/kt14498.kt new file mode 100644 index 00000000000..dc25b6cfb22 --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/kt14498.kt @@ -0,0 +1,17 @@ +// !DIAGNOSTICS: -UNUSED_TYPEALIAS_PARAMETER + +interface I1 +interface Out +interface InvOut + +typealias A1 = I1 +typealias A2 = I1 +typealias AOut = Out +typealias AInvOut = InvOut +typealias AInvOutTT = AInvOut + +class Test1 : A1 +class Test2 : A2 +class Test3 : AOut +class Test4 : AInvOut +class Test5 : AInvOutTT \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/typealias/kt14498.txt b/compiler/testData/diagnostics/tests/typealias/kt14498.txt new file mode 100644 index 00000000000..e8eb39f2dae --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/kt14498.txt @@ -0,0 +1,59 @@ +package + +public interface I1 { + 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 InvOut { + 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 Out { + 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 Test1 : A1 /* = I1 */ { + public constructor Test1() + 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 Test2 : A2 /* = I1 */ { + public constructor Test2() + 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 Test3 : AOut /* = Out */ { + public constructor Test3() + 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 Test4 : AInvOut /* = InvOut */ { + public constructor Test4() + 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 Test5 : AInvOutTT /* = InvOut */ { + public constructor Test5() + 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 A1 = I1 +public typealias A2 = I1 +public typealias AInvOut = InvOut +public typealias AInvOutTT = AInvOut +public typealias AOut = Out diff --git a/compiler/testData/diagnostics/tests/typealias/kt14498a.kt b/compiler/testData/diagnostics/tests/typealias/kt14498a.kt new file mode 100644 index 00000000000..69598f1bfb7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/kt14498a.kt @@ -0,0 +1,11 @@ +interface Out +interface Inv +typealias A1 = Out> +typealias A2 = Out> +typealias A3 = Inv> +typealias A4 = Out> + +interface Q1 : Out> +interface Q2 : Out> +interface Q3 : Out<A3> +interface Q4 : Out<A4> \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/typealias/kt14498a.txt b/compiler/testData/diagnostics/tests/typealias/kt14498a.txt new file mode 100644 index 00000000000..d2a1cdd8bd2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/kt14498a.txt @@ -0,0 +1,41 @@ +package + +public interface Inv { + 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 Out { + 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 Q1 : Out /* = Out> */> { + 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 Q2 : Out /* = Out> */> { + 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 Q3 : Out /* = Inv> */> { + 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 Q4 : Out /* = Out> */> { + 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 A1 = Out> +public typealias A2 = Out> +public typealias A3 = Inv> +public typealias A4 = Out> diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 05e1ebbde01..8218b6c3fc0 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -20736,6 +20736,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("kt14498.kt") + public void testKt14498() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/kt14498.kt"); + doTest(fileName); + } + + @TestMetadata("kt14498a.kt") + public void testKt14498a() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/kt14498a.kt"); + doTest(fileName); + } + @TestMetadata("localTypeAlias.kt") public void testLocalTypeAlias() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/localTypeAlias.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/VarianceChecker.kt b/core/descriptors/src/org/jetbrains/kotlin/types/VarianceChecker.kt index 90c09ad11ff..5242e528f8e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/VarianceChecker.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/VarianceChecker.kt @@ -38,7 +38,6 @@ fun > D.checkTypePosition( reportError: (TypeParameterDescriptor, D, Variance) -> Unit = DO_NOTHING_3, customVariance: (TypeParameterDescriptor) -> Variance? = { null } ): Boolean { - flexibleBounds?.let { return it.first.checkTypePosition(position, reportError, customVariance) and it.second.checkTypePosition(position, reportError, customVariance) diff --git a/idea/testData/diagnosticMessage/typeVarianceConflictInTypeAliasExpansion.kt b/idea/testData/diagnosticMessage/typeVarianceConflictInTypeAliasExpansion.kt new file mode 100644 index 00000000000..12ee2edeb53 --- /dev/null +++ b/idea/testData/diagnosticMessage/typeVarianceConflictInTypeAliasExpansion.kt @@ -0,0 +1,10 @@ +// !DIAGNOSTICS_NUMBER: 1 +// !DIAGNOSTICS: TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE +// !MESSAGE_TYPE: TEXT + +interface InvOut + +typealias AInvOut = InvOut +typealias AInvOutTT = AInvOut + +class Test : AInvOutTT \ No newline at end of file diff --git a/idea/testData/diagnosticMessage/typeVarianceConflictInTypeAliasExpansion1.txt b/idea/testData/diagnosticMessage/typeVarianceConflictInTypeAliasExpansion1.txt new file mode 100644 index 00000000000..68c574288a4 --- /dev/null +++ b/idea/testData/diagnosticMessage/typeVarianceConflictInTypeAliasExpansion1.txt @@ -0,0 +1,2 @@ + +Type parameter S is declared as 'out' but occurs in 'invariant' position in abbreviated type AInvOutTT /* = InvOut */ \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/highlighter/DiagnosticMessageTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/highlighter/DiagnosticMessageTestGenerated.java index 5bf59000559..c7fda336374 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/highlighter/DiagnosticMessageTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/highlighter/DiagnosticMessageTestGenerated.java @@ -275,6 +275,12 @@ public class DiagnosticMessageTestGenerated extends AbstractDiagnosticMessageTes doTest(fileName); } + @TestMetadata("typeVarianceConflictInTypeAliasExpansion.kt") + public void testTypeVarianceConflictInTypeAliasExpansion() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/diagnosticMessage/typeVarianceConflictInTypeAliasExpansion.kt"); + doTest(fileName); + } + @TestMetadata("unsupportedFeature.kt") public void testUnsupportedFeature() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/diagnosticMessage/unsupportedFeature.kt");