diff --git a/compiler/testData/diagnostics/tests/regressions/kt14740.kt b/compiler/testData/diagnostics/tests/regressions/kt14740.kt new file mode 100644 index 00000000000..411e8dcbe5a --- /dev/null +++ b/compiler/testData/diagnostics/tests/regressions/kt14740.kt @@ -0,0 +1,20 @@ +// FILE: Foo.java +public abstract class Foo { + + public interface Transformer {} + public interface LifecycleTransformer extends Transformer {} + + public class Observable { + public Observable compose(Transformer transformer) { + return null; + } + } + + + public final LifecycleTransformer bindToLifecycle() { + return null; + } +} + +// FILE: 1.kt +fun Foo.Observable.bindTo(a: Foo): Foo.Observable = compose(a.bindToLifecycle()) \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/regressions/kt14740.txt b/compiler/testData/diagnostics/tests/regressions/kt14740.txt new file mode 100644 index 00000000000..18d8e922ee1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/regressions/kt14740.txt @@ -0,0 +1,31 @@ +package + +public fun Foo.Observable.bindTo(/*0*/ a: Foo): Foo.Observable + +public abstract class Foo { + public constructor Foo() + public final fun bindToLifecycle(): Foo.LifecycleTransformer! + 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 LifecycleTransformer : Foo.Transformer { + 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 open inner class Observable { + public constructor Observable() + public open fun compose(/*0*/ transformer: Foo.Transformer!): Foo.Observable! + 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 Transformer { + 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 744cd22598f..6b0353e51b9 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -16111,6 +16111,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("kt14740.kt") + public void testKt14740() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/regressions/kt14740.kt"); + doTest(fileName); + } + @TestMetadata("kt1489_1728.kt") public void testKt1489_1728() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/regressions/kt1489_1728.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewKotlinTypeChecker.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewKotlinTypeChecker.kt index 462697de3f0..86aa64d191e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewKotlinTypeChecker.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewKotlinTypeChecker.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.resolve.calls.inference.CapturedType +import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructor import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.TypeCheckerContext.SupertypesPolicy @@ -101,14 +102,16 @@ object NewKotlinTypeChecker : KotlinTypeChecker { } fun transformToNewType(type: SimpleType): SimpleType { - if (type is CapturedType) { - val lowerType = type.typeProjection.check { it.projectionKind == Variance.IN_VARIANCE }?.type?.unwrap() + // Type itself can be just SimpleTypeImpl, not CapturedType. see KT-16147 + if (type.constructor is CapturedTypeConstructor) { + val constructor = type.constructor as CapturedTypeConstructor + val lowerType = constructor.typeProjection.check { it.projectionKind == Variance.IN_VARIANCE }?.type?.unwrap() // it is incorrect calculate this type directly because of recursive star projections - if (type.constructor.newTypeConstructor == null) { - type.constructor.newTypeConstructor = NewCapturedTypeConstructor(type.typeProjection, type.constructor.supertypes.map { it.unwrap() }) + if (constructor.newTypeConstructor == null) { + constructor.newTypeConstructor = NewCapturedTypeConstructor(constructor.typeProjection, constructor.supertypes.map { it.unwrap() }) } - val newCapturedType = NewCapturedType(CaptureStatus.FOR_SUBTYPING, type.constructor.newTypeConstructor!!, + val newCapturedType = NewCapturedType(CaptureStatus.FOR_SUBTYPING, constructor.newTypeConstructor!!, lowerType, type.annotations, type.isMarkedNullable) return newCapturedType }