diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 7a17f5fc644..71488bcc889 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -328,6 +328,7 @@ public interface Errors { DiagnosticFactory0 DELEGATED_PROPERTY_INSIDE_INLINE_CLASS = DiagnosticFactory0.create(ERROR); DiagnosticFactory1 INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE = DiagnosticFactory1.create(ERROR); DiagnosticFactory0 INLINE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 INLINE_CLASS_CANNOT_EXTEND_CLASSES = DiagnosticFactory0.create(ERROR); // Secondary constructors 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 58a5e11c9e1..7f53db8218b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -657,6 +657,7 @@ public class DefaultErrorMessages { MAP.put(DELEGATED_PROPERTY_INSIDE_INLINE_CLASS, "Inline class cannot have delegated properties"); MAP.put(INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE, "Inline class cannot have value parameter of type ''{0}''", RENDER_TYPE); MAP.put(INLINE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION, "Inline class cannot implement an interface by delegation"); + MAP.put(INLINE_CLASS_CANNOT_EXTEND_CLASSES, "Inline class cannot extend classes"); MAP.put(VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED, "Variance annotations are only allowed for type parameters of classes and interfaces"); MAP.put(BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED, "Bounds are not allowed on type alias parameters"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt index 218ff6d9b10..e86e8759a77 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt @@ -92,6 +92,14 @@ object InlineClassDeclarationChecker : DeclarationChecker { if (supertypeEntry is KtDelegatedSuperTypeEntry) { trace.report(Errors.INLINE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION.on(supertypeEntry)) return + } else { + val typeReference = supertypeEntry.typeReference ?: continue + val type = trace[BindingContext.TYPE, typeReference] ?: continue + val typeDescriptor = type.constructor.declarationDescriptor ?: continue + if (!DescriptorUtils.isInterface(typeDescriptor)) { + trace.report(Errors.INLINE_CLASS_CANNOT_EXTEND_CLASSES.on(typeReference)) + return + } } } } diff --git a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.kt b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.kt new file mode 100644 index 00000000000..7a8e6c3bb01 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.kt @@ -0,0 +1,13 @@ +// !LANGUAGE: +InlineClasses + +abstract class AbstractBaseClass + +open class OpenBaseClass + +interface BaseInterface + +inline class TestExtendsAbstractClass(val x: Int) : AbstractBaseClass() + +inline class TestExtendsOpenClass(val x: Int) : OpenBaseClass() + +inline class TestImplementsInterface(val x: Int) : BaseInterface \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.txt b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.txt new file mode 100644 index 00000000000..2cc5965919b --- /dev/null +++ b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.txt @@ -0,0 +1,45 @@ +package + +public abstract class AbstractBaseClass { + public constructor AbstractBaseClass() + 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 BaseInterface { + 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 class OpenBaseClass { + public constructor OpenBaseClass() + 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 inline class TestExtendsAbstractClass : AbstractBaseClass { + public constructor TestExtendsAbstractClass(/*0*/ x: kotlin.Int) + public final val x: kotlin.Int + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} + +public final inline class TestExtendsOpenClass : OpenBaseClass { + public constructor TestExtendsOpenClass(/*0*/ x: kotlin.Int) + public final val x: kotlin.Int + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} + +public final inline class TestImplementsInterface : BaseInterface { + public constructor TestImplementsInterface(/*0*/ x: kotlin.Int) + public final val x: kotlin.Int + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ 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 676eab44eef..7340fe58713 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -10867,6 +10867,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/inlineClasses/identityComparisonWithInlineClasses.kt"); } + @TestMetadata("inlineClassCanOnlyImplementInterfaces.kt") + public void testInlineClassCanOnlyImplementInterfaces() throws Exception { + runTest("compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.kt"); + } + @TestMetadata("inlineClassCannotImplementInterfaceByDelegation.kt") public void testInlineClassCannotImplementInterfaceByDelegation() throws Exception { runTest("compiler/testData/diagnostics/tests/inlineClasses/inlineClassCannotImplementInterfaceByDelegation.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 16ff775420b..4bff27ed11a 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -10867,6 +10867,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inlineClasses/identityComparisonWithInlineClasses.kt"); } + @TestMetadata("inlineClassCanOnlyImplementInterfaces.kt") + public void testInlineClassCanOnlyImplementInterfaces() throws Exception { + runTest("compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.kt"); + } + @TestMetadata("inlineClassCannotImplementInterfaceByDelegation.kt") public void testInlineClassCannotImplementInterfaceByDelegation() throws Exception { runTest("compiler/testData/diagnostics/tests/inlineClasses/inlineClassCannotImplementInterfaceByDelegation.kt");