diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index ffa29b37acb..5586a5e7cb9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -574,6 +574,10 @@ public class DescriptorResolver { BindingTrace trace ) { if (!TypeUtils.canHaveSubtypes(JetTypeChecker.DEFAULT, upperBoundType)) { + ClassifierDescriptor descriptor = upperBoundType.getConstructor().getDeclarationDescriptor(); + if (descriptor instanceof ClassDescriptor) { + if (((ClassDescriptor) descriptor).getModality() == Modality.SEALED) return; + } trace.report(FINAL_UPPER_BOUND.on(upperBound, upperBoundType)); } if (TypesPackage.isDynamic(upperBoundType)) { diff --git a/compiler/testData/diagnostics/tests/sealed/NotFinal.kt b/compiler/testData/diagnostics/tests/sealed/NotFinal.kt new file mode 100644 index 00000000000..0cf7cf13a5b --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NotFinal.kt @@ -0,0 +1,10 @@ +// See KT-9244 + +sealed class Foo { + class Bar : Foo() + class Baz : Foo() +} + +// The following warning seems incorrect here +// "Foo is a final type, and thus a value of the type parameter is predetermined" +fun doit(arg: T): T = arg \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/sealed/NotFinal.txt b/compiler/testData/diagnostics/tests/sealed/NotFinal.txt new file mode 100644 index 00000000000..3d5953b9dfc --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NotFinal.txt @@ -0,0 +1,24 @@ +package + +public fun doit(/*0*/ arg: T): T + +public sealed class Foo { + private constructor Foo() + 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 Bar : Foo { + public constructor Bar() + 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 Baz : Foo { + public constructor Baz() + 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/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 981c60b020a..1825181c122 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -13263,6 +13263,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("NotFinal.kt") + public void testNotFinal() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NotFinal.kt"); + doTest(fileName); + } + @TestMetadata("OperationWhen.kt") public void testOperationWhen() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/OperationWhen.kt");