diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java index 5d7f06f211a..9aacd68bbf5 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java @@ -8031,6 +8031,16 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok runTest("compiler/testData/diagnostics/tests/generics/doNotCaptureSupertype.kt"); } + @TestMetadata("finalUpperBoundWithOverride.kt") + public void testFinalUpperBoundWithOverride() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/finalUpperBoundWithOverride.kt"); + } + + @TestMetadata("finalUpperBoundWithoutOverride.kt") + public void testFinalUpperBoundWithoutOverride() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/finalUpperBoundWithoutOverride.kt"); + } + @TestMetadata("genericsInType.kt") public void testGenericsInType() throws Exception { runTest("compiler/testData/diagnostics/tests/generics/genericsInType.kt"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index f046c89c5bf..2daf1596a72 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt @@ -369,7 +369,7 @@ class DeclarationsChecker( upperBoundCheckRequests.add(DescriptorResolver.UpperBoundCheckRequest(name, typeReference, type)) } - DescriptorResolver.checkUpperBoundTypes(trace, upperBoundCheckRequests) + DescriptorResolver.checkUpperBoundTypes(trace, upperBoundCheckRequests, false) for (request in upperBoundCheckRequests) { DescriptorResolver.checkBounds(request.upperBound, request.upperBoundType, trace) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index 0bea6f7c2bb..26b756057ff 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -560,12 +560,16 @@ public class DescriptorResolver { } if (!(declaration instanceof KtClass)) { - checkUpperBoundTypes(trace, upperBoundCheckRequests); + checkUpperBoundTypes(trace, upperBoundCheckRequests, declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)); checkNamesInConstraints(declaration, descriptor, scope, trace); } } - public static void checkUpperBoundTypes(@NotNull BindingTrace trace, @NotNull List requests) { + public static void checkUpperBoundTypes( + @NotNull BindingTrace trace, + @NotNull List requests, + boolean hasOverrideModifier + ) { if (requests.isEmpty()) return; Set classBoundEncountered = new HashSet<>(); @@ -593,7 +597,7 @@ public class DescriptorResolver { } } - checkUpperBoundType(upperBoundElement, upperBound, trace); + checkUpperBoundType(upperBoundElement, upperBound, trace, hasOverrideModifier); } } @@ -641,9 +645,10 @@ public class DescriptorResolver { public static void checkUpperBoundType( KtTypeReference upperBound, @NotNull KotlinType upperBoundType, - BindingTrace trace + BindingTrace trace, + boolean hasOverrideModifier ) { - if (!TypeUtils.canHaveSubtypes(KotlinTypeChecker.DEFAULT, upperBoundType)) { + if (!hasOverrideModifier && !TypeUtils.canHaveSubtypes(KotlinTypeChecker.DEFAULT, upperBoundType)) { trace.report(FINAL_UPPER_BOUND.on(upperBound, upperBoundType)); } if (DynamicTypesKt.isDynamic(upperBoundType)) { diff --git a/compiler/testData/diagnostics/tests/generics/finalUpperBoundWithOverride.kt b/compiler/testData/diagnostics/tests/generics/finalUpperBoundWithOverride.kt new file mode 100644 index 00000000000..26449d3c54c --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/finalUpperBoundWithOverride.kt @@ -0,0 +1,97 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER +// SKIP_TXT +// Issues: KT-25105 + +class Message1 +class Task +object Message2 +enum class Message3 +data class Message4(val x: Int) + +sealed class Message5 { + open fun execute() {} +} + +interface Manager { + fun execute1(task: Task) {} + fun Int> execute2(task: T) {} + fun Message2> execute3() {} + fun execute4() {} + fun execute5() {} + val A.x get() = 10 + var A.y + get() = 10 + set(value) {} +} + +object MessageManager1 : Manager { + override fun execute1(task: Task) {} + override fun execute2(task: T) {} + override fun execute3() {} +} + +object MessageManager2 : Manager { + override fun execute4() {} +} + +object MessageManager3 : Manager { + override fun execute5() {} +} + +class MessageManager4 : Manager { + override fun execute1(task: Task) {} + override fun execute2(task: T) {} + override fun execute3() {} +} + +class MessageManager5 : Manager { + override fun execute4() {} +} + +class MessageManager6 : Manager { + override fun execute5() {} +} + +interface MessageManager7 : Manager { + override fun execute5() {} +} + +interface MessageManager8 : Manager { + override fun execute1(task: Task) {} + override fun execute2(task: T) {} + override fun execute3() {} +} + +interface MessageManager9 : Manager { + override fun execute4() {} +} + +object MessageManager10 : Message5() { + override fun execute() {} +} + +class MessageManager11 : Message5>() { + override fun > execute() {} +} + +data class MessageManager12(val x: Int) : Message5() { + override fun execute() {} +} + +sealed class MessageManager13 : Message5() { + override fun execute() {} +} + +class MessageManager14 : Manager { + override val T.x get() = 10 + override var T.y + get() = 10 + set(value) {} +} + +object MessageManager15 : Manager { + override val T.x get() = 10 + override var T.y + get() = 10 + set(value) {} +} diff --git a/compiler/testData/diagnostics/tests/generics/finalUpperBoundWithoutOverride.kt b/compiler/testData/diagnostics/tests/generics/finalUpperBoundWithoutOverride.kt new file mode 100644 index 00000000000..546c9eab658 --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/finalUpperBoundWithoutOverride.kt @@ -0,0 +1,82 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER +// SKIP_TXT +// Issues: KT-25105 + +class Message1 +class Task +object Message2 +enum class Message3 +data class Message4(val x: Int) +interface Manager {} + +object MessageManager1 : Manager { + fun Message1> execute1(task: Task) {} + fun Int> execute2(task: T) {} + fun Message2> execute3() {} +} + +object MessageManager2 : Manager { + fun execute4() {} +} + +object MessageManager3 : Manager { + fun Message4> execute5() {} +} + +class MessageManager4 : Manager { + fun Message1> execute1(task: Task) {} + fun Int> execute2(task: T) {} + fun Message2> execute3() {} +} + +class MessageManager5 : Manager { + fun execute4() {} +} + +class MessageManager6 : Manager { + fun Message4> execute5() {} +} + +interface MessageManager7 : Manager { + fun Message4> execute5() {} +} + +interface MessageManager8 : Manager { + fun Message1> execute1(task: Task) {} + fun Int> execute2(task: T) {} + fun Message2> execute3() {} +} + +interface MessageManager9 : Manager { + fun execute4() {} +} + +object MessageManager10 : Message5() { + fun Int> execute() {} +} + +class MessageManager11 : Message5<Message5>() { + fun Message5> execute() {} +} + +data class MessageManager12(val x: Int) : Message5() { + fun Message2> execute() {} +} + +sealed class MessageManager13 : Message5() { + fun execute() {} +} + +class MessageManager14 : Manager { + val Message2> T.x get() = 10 + var Message2> T.y + get() = 10 + set(value) {} +} + +object MessageManager15 : Manager { + val Int> T.x get() = 10 + var Int> T.y + get() = 10 + set(value) {} +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 6b57dedf397..34b016ad086 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -8038,6 +8038,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/generics/doNotCaptureSupertype.kt"); } + @TestMetadata("finalUpperBoundWithOverride.kt") + public void testFinalUpperBoundWithOverride() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/finalUpperBoundWithOverride.kt"); + } + + @TestMetadata("finalUpperBoundWithoutOverride.kt") + public void testFinalUpperBoundWithoutOverride() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/finalUpperBoundWithoutOverride.kt"); + } + @TestMetadata("genericsInType.kt") public void testGenericsInType() throws Exception { runTest("compiler/testData/diagnostics/tests/generics/genericsInType.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 17d1cd80c5c..1ea274dc59d 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -8033,6 +8033,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/generics/doNotCaptureSupertype.kt"); } + @TestMetadata("finalUpperBoundWithOverride.kt") + public void testFinalUpperBoundWithOverride() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/finalUpperBoundWithOverride.kt"); + } + + @TestMetadata("finalUpperBoundWithoutOverride.kt") + public void testFinalUpperBoundWithoutOverride() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/finalUpperBoundWithoutOverride.kt"); + } + @TestMetadata("genericsInType.kt") public void testGenericsInType() throws Exception { runTest("compiler/testData/diagnostics/tests/generics/genericsInType.kt");