diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpander.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpander.kt index 2cc9411bfbb..5c9fcdd048d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpander.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpander.kt @@ -50,7 +50,7 @@ class TypeAliasExpander( "Type alias expansion: result for ${typeAliasExpansion.descriptor} is ${expandedProjection.projectionKind}, should be invariant" } - val expandedTypeWithExtraAnnotations = combineAnnotations(expandedType, annotations) + val expandedTypeWithExtraAnnotations = expandedType.combineAnnotations(annotations) return if (withAbbreviatedType) expandedTypeWithExtraAnnotations.withAbbreviation(typeAliasExpansion.createAbbreviation(underlyingProjection, annotations)) @@ -58,8 +58,8 @@ class TypeAliasExpander( expandedTypeWithExtraAnnotations } - private fun combineAnnotations(type: SimpleType, annotations: Annotations): SimpleType { - val existingAnnotationTypes = type.annotations.getAllAnnotations().mapTo(hashSetOf()) { it.annotation.type } + private fun SimpleType.combineAnnotations(annotations: Annotations): SimpleType { + val existingAnnotationTypes = this.annotations.getAllAnnotations().mapTo(hashSetOf()) { it.annotation.type } for (annotation in annotations) { if (annotation.type in existingAnnotationTypes) { @@ -67,7 +67,7 @@ class TypeAliasExpander( } } - return type.replace(newAnnotations = CompositeAnnotations(listOf(annotations, type.annotations))) + return replace(newAnnotations = CompositeAnnotations(listOf(annotations, this.annotations))) } private fun TypeAliasExpansion.createAbbreviation(originalProjection: TypeProjection, annotations: Annotations) = @@ -85,6 +85,7 @@ class TypeAliasExpander( typeParameterDescriptor: TypeParameterDescriptor?, recursionDepth: Int ): TypeProjection { + // TODO refactor TypeSubstitutor to introduce custom diagnostics assertRecursionDepth(recursionDepth, typeAliasExpansion.descriptor) if (underlyingProjection.isStarProjection) return TypeUtils.makeStarProjection(typeParameterDescriptor!!) @@ -100,13 +101,15 @@ class TypeAliasExpander( val argumentVariance = argument.projectionKind val underlyingVariance = underlyingProjection.projectionKind + val argumentType = argument.type as? SimpleType ?: throw AssertionError("Non-simple type in type alias argument: $argument") + val substitutionVariance = when { underlyingVariance == argumentVariance -> argumentVariance underlyingVariance == Variance.INVARIANT -> argumentVariance argumentVariance == Variance.INVARIANT -> underlyingVariance else -> { - reportStrategy.conflictingProjection(typeAliasExpansion.descriptor, typeParameterDescriptor, argument.type) + reportStrategy.conflictingProjection(typeAliasExpansion.descriptor, typeParameterDescriptor, argumentType) argumentVariance } } @@ -118,12 +121,13 @@ class TypeAliasExpander( parameterVariance == Variance.INVARIANT -> substitutionVariance substitutionVariance == Variance.INVARIANT -> Variance.INVARIANT else -> { - reportStrategy.conflictingProjection(typeAliasExpansion.descriptor, typeParameterDescriptor, argument.type) + reportStrategy.conflictingProjection(typeAliasExpansion.descriptor, typeParameterDescriptor, argumentType) substitutionVariance } } - val substitutedType = TypeUtils.makeNullableIfNeeded(argument.type, underlyingType.isMarkedNullable) + val substitutedType = TypeUtils.makeNullableIfNeeded(argumentType, underlyingType.isMarkedNullable) + .combineAnnotations(underlyingType.annotations) return TypeProjectionImpl(resultingVariance, substitutedType) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpansion.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpansion.kt index 6c8799fad98..f97e893344a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpansion.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeAliasExpansion.kt @@ -16,14 +16,10 @@ package org.jetbrains.kotlin.resolve -import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor -import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.TypeProjection -import org.jetbrains.kotlin.types.TypeUtils -import org.jetbrains.kotlin.types.typeUtil.contains class TypeAliasExpansion private constructor( val parent: TypeAliasExpansion?, diff --git a/compiler/testData/diagnostics/tests/typealias/parameterSubstitution.txt b/compiler/testData/diagnostics/tests/typealias/parameterSubstitution.txt index 14f96b3cb65..277dae7348c 100644 --- a/compiler/testData/diagnostics/tests/typealias/parameterSubstitution.txt +++ b/compiler/testData/diagnostics/tests/typealias/parameterSubstitution.txt @@ -1,7 +1,7 @@ package public val ca1: CA /* = C */ -public val ca2: CA /* = C */> /* = C /* = C */> */ +public val ca2: CA /* = C */> /* = C> */ public val ca3: CA> /* = C> */ public val ca4: CA /* = C */ diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasForProjectionInSuperInterfaces.txt b/compiler/testData/diagnostics/tests/typealias/typeAliasForProjectionInSuperInterfaces.txt index ff2d20367cb..1eac1138f61 100644 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasForProjectionInSuperInterfaces.txt +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasForProjectionInSuperInterfaces.txt @@ -34,7 +34,7 @@ public final class Test4 : IT<*> /* = I<*> */ { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } -public final class Test5 : IT /* = I<*> */> /* = I /* = I<*> */> */ { +public final class Test5 : IT /* = I<*> */> /* = I> */ { 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 diff --git a/compiler/testData/diagnostics/tests/typealias/typealiasRhsAnnotationsInArguments.kt b/compiler/testData/diagnostics/tests/typealias/typealiasRhsAnnotationsInArguments.kt new file mode 100644 index 00000000000..1f635bb621a --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/typealiasRhsAnnotationsInArguments.kt @@ -0,0 +1,11 @@ +@Target(AnnotationTarget.TYPE) +annotation class Ann1 + +@Target(AnnotationTarget.TYPE) +annotation class Ann2 + +class C + +typealias CA = C<@Ann1 T> + +fun test(x: CA<@Ann2 Int>) = x \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/typealias/typealiasRhsAnnotationsInArguments.txt b/compiler/testData/diagnostics/tests/typealias/typealiasRhsAnnotationsInArguments.txt new file mode 100644 index 00000000000..3082f907706 --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/typealiasRhsAnnotationsInArguments.txt @@ -0,0 +1,25 @@ +package + +public fun test(/*0*/ x: CA<@Ann2 kotlin.Int> /* = C<@Ann1 @Ann2 kotlin.Int> */): CA<@Ann2 kotlin.Int> /* = C<@Ann1 @Ann2 kotlin.Int> */ + +@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE}) public final annotation class Ann1 : kotlin.Annotation { + public constructor Ann1() + 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 +} + +@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE}) public final annotation class Ann2 : kotlin.Annotation { + public constructor Ann2() + 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 C { + public constructor C() + 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 CA = C<@Ann1 T> diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index a999be41237..5e7383eff38 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -21286,6 +21286,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("typealiasRhsAnnotationsInArguments.kt") + public void testTypealiasRhsAnnotationsInArguments() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typealiasRhsAnnotationsInArguments.kt"); + doTest(fileName); + } + @TestMetadata("typealiasRhsRepeatedAnnotations.kt") public void testTypealiasRhsRepeatedAnnotations() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typealiasRhsRepeatedAnnotations.kt");