Exclude warning "Remove final upper bound" for functions with override modifier
^KT-25105 Fixed
This commit is contained in:
+10
@@ -8031,6 +8031,16 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
|||||||
runTest("compiler/testData/diagnostics/tests/generics/doNotCaptureSupertype.kt");
|
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")
|
@TestMetadata("genericsInType.kt")
|
||||||
public void testGenericsInType() throws Exception {
|
public void testGenericsInType() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/generics/genericsInType.kt");
|
runTest("compiler/testData/diagnostics/tests/generics/genericsInType.kt");
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ class DeclarationsChecker(
|
|||||||
upperBoundCheckRequests.add(DescriptorResolver.UpperBoundCheckRequest(name, typeReference, type))
|
upperBoundCheckRequests.add(DescriptorResolver.UpperBoundCheckRequest(name, typeReference, type))
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorResolver.checkUpperBoundTypes(trace, upperBoundCheckRequests)
|
DescriptorResolver.checkUpperBoundTypes(trace, upperBoundCheckRequests, false)
|
||||||
|
|
||||||
for (request in upperBoundCheckRequests) {
|
for (request in upperBoundCheckRequests) {
|
||||||
DescriptorResolver.checkBounds(request.upperBound, request.upperBoundType, trace)
|
DescriptorResolver.checkBounds(request.upperBound, request.upperBoundType, trace)
|
||||||
|
|||||||
@@ -560,12 +560,16 @@ public class DescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(declaration instanceof KtClass)) {
|
if (!(declaration instanceof KtClass)) {
|
||||||
checkUpperBoundTypes(trace, upperBoundCheckRequests);
|
checkUpperBoundTypes(trace, upperBoundCheckRequests, declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD));
|
||||||
checkNamesInConstraints(declaration, descriptor, scope, trace);
|
checkNamesInConstraints(declaration, descriptor, scope, trace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkUpperBoundTypes(@NotNull BindingTrace trace, @NotNull List<UpperBoundCheckRequest> requests) {
|
public static void checkUpperBoundTypes(
|
||||||
|
@NotNull BindingTrace trace,
|
||||||
|
@NotNull List<UpperBoundCheckRequest> requests,
|
||||||
|
boolean hasOverrideModifier
|
||||||
|
) {
|
||||||
if (requests.isEmpty()) return;
|
if (requests.isEmpty()) return;
|
||||||
|
|
||||||
Set<Name> classBoundEncountered = new HashSet<>();
|
Set<Name> 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(
|
public static void checkUpperBoundType(
|
||||||
KtTypeReference upperBound,
|
KtTypeReference upperBound,
|
||||||
@NotNull KotlinType upperBoundType,
|
@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));
|
trace.report(FINAL_UPPER_BOUND.on(upperBound, upperBoundType));
|
||||||
}
|
}
|
||||||
if (DynamicTypesKt.isDynamic(upperBoundType)) {
|
if (DynamicTypesKt.isDynamic(upperBoundType)) {
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// SKIP_TXT
|
||||||
|
// Issues: KT-25105
|
||||||
|
|
||||||
|
class Message1
|
||||||
|
class Task<T>
|
||||||
|
object Message2
|
||||||
|
enum class Message3
|
||||||
|
data class Message4(val x: Int)
|
||||||
|
|
||||||
|
sealed class Message5<T> {
|
||||||
|
open fun <A : T> execute() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Manager<T> {
|
||||||
|
fun <A : T> execute1(task: Task<A>) {}
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Int<!>> execute2(task: T) {}
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Message2<!>> execute3() {}
|
||||||
|
fun <A : T> execute4() {}
|
||||||
|
fun <A : T> execute5() {}
|
||||||
|
val <A : T> A.x get() = 10
|
||||||
|
var <A : T> A.y
|
||||||
|
get() = 10
|
||||||
|
set(value) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
object MessageManager1 : Manager<Message1> {
|
||||||
|
override fun <T : Message1> execute1(task: Task<T>) {}
|
||||||
|
override fun <T : Int> execute2(task: T) {}
|
||||||
|
override fun <T : Message2> execute3() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
object MessageManager2 : Manager<Message3> {
|
||||||
|
override fun <T : Message3> execute4() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
object MessageManager3 : Manager<Message4> {
|
||||||
|
override fun <T : Message4> execute5() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageManager4 : Manager<Message1> {
|
||||||
|
override fun <T : Message1> execute1(task: Task<T>) {}
|
||||||
|
override fun <T : Int> execute2(task: T) {}
|
||||||
|
override fun <T : Message2> execute3() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageManager5 : Manager<Message3> {
|
||||||
|
override fun <T : Message3> execute4() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageManager6 : Manager<Message4> {
|
||||||
|
override fun <T : Message4> execute5() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MessageManager7 : Manager<Message4> {
|
||||||
|
override fun <T : Message4> execute5() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MessageManager8 : Manager<Message1> {
|
||||||
|
override fun <T : Message1> execute1(task: Task<T>) {}
|
||||||
|
override fun <T : Int> execute2(task: T) {}
|
||||||
|
override fun <T : Message2> execute3() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MessageManager9 : Manager<Message3> {
|
||||||
|
override fun <T : Message3> execute4() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
object MessageManager10 : Message5<Int>() {
|
||||||
|
override fun <T : Int> execute() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageManager11<A> : Message5<Message5<A>>() {
|
||||||
|
override fun <T : Message5<A>> execute() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class MessageManager12(val x: Int) : Message5<Message2>() {
|
||||||
|
override fun <T : Message2> execute() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class MessageManager13<A> : Message5<A>() {
|
||||||
|
override fun <T : A> execute() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageManager14 : Manager<Message2> {
|
||||||
|
override val <T : Message2> T.x get() = 10
|
||||||
|
override var <T : Message2> T.y
|
||||||
|
get() = 10
|
||||||
|
set(value) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
object MessageManager15 : Manager<Int> {
|
||||||
|
override val <T : Int> T.x get() = 10
|
||||||
|
override var <T : Int> T.y
|
||||||
|
get() = 10
|
||||||
|
set(value) {}
|
||||||
|
}
|
||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// SKIP_TXT
|
||||||
|
// Issues: KT-25105
|
||||||
|
|
||||||
|
class Message1
|
||||||
|
class Task<T>
|
||||||
|
object Message2
|
||||||
|
enum class Message3
|
||||||
|
data class Message4(val x: Int)
|
||||||
|
interface Manager<T> {}
|
||||||
|
|
||||||
|
object MessageManager1 : Manager<Message1> {
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Message1<!>> execute1(task: Task<T>) {}
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Int<!>> execute2(task: T) {}
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Message2<!>> execute3() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
object MessageManager2 : Manager<Message3> {
|
||||||
|
fun <T : Message3> execute4() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
object MessageManager3 : Manager<Message4> {
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Message4<!>> execute5() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageManager4 : Manager<Message1> {
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Message1<!>> execute1(task: Task<T>) {}
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Int<!>> execute2(task: T) {}
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Message2<!>> execute3() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageManager5 : Manager<Message3> {
|
||||||
|
fun <T : Message3> execute4() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageManager6 : Manager<Message4> {
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Message4<!>> execute5() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MessageManager7 : Manager<Message4> {
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Message4<!>> execute5() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MessageManager8 : Manager<Message1> {
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Message1<!>> execute1(task: Task<T>) {}
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Int<!>> execute2(task: T) {}
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Message2<!>> execute3() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MessageManager9 : Manager<Message3> {
|
||||||
|
fun <T : Message3> execute4() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
object MessageManager10 : <!UNRESOLVED_REFERENCE!>Message5<!><Int>() {
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Int<!>> execute() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageManager11<A> : <!UNRESOLVED_REFERENCE!>Message5<!><<!UNRESOLVED_REFERENCE!>Message5<!><A>>() {
|
||||||
|
fun <T : <!UNRESOLVED_REFERENCE!>Message5<!><A>> execute() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class MessageManager12(val x: Int) : <!UNRESOLVED_REFERENCE!>Message5<!><Message2>() {
|
||||||
|
fun <T : <!FINAL_UPPER_BOUND!>Message2<!>> execute() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class MessageManager13<A> : <!UNRESOLVED_REFERENCE!>Message5<!><A>() {
|
||||||
|
fun <T : A> execute() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageManager14 : Manager<Message2> {
|
||||||
|
val <T : <!FINAL_UPPER_BOUND!>Message2<!>> T.x get() = 10
|
||||||
|
var <T : <!FINAL_UPPER_BOUND!>Message2<!>> T.y
|
||||||
|
get() = 10
|
||||||
|
set(value) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
object MessageManager15 : Manager<Int> {
|
||||||
|
val <T : <!FINAL_UPPER_BOUND!>Int<!>> T.x get() = 10
|
||||||
|
var <T : <!FINAL_UPPER_BOUND!>Int<!>> T.y
|
||||||
|
get() = 10
|
||||||
|
set(value) {}
|
||||||
|
}
|
||||||
@@ -8038,6 +8038,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/generics/doNotCaptureSupertype.kt");
|
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")
|
@TestMetadata("genericsInType.kt")
|
||||||
public void testGenericsInType() throws Exception {
|
public void testGenericsInType() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/generics/genericsInType.kt");
|
runTest("compiler/testData/diagnostics/tests/generics/genericsInType.kt");
|
||||||
|
|||||||
Generated
+10
@@ -8033,6 +8033,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
runTest("compiler/testData/diagnostics/tests/generics/doNotCaptureSupertype.kt");
|
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")
|
@TestMetadata("genericsInType.kt")
|
||||||
public void testGenericsInType() throws Exception {
|
public void testGenericsInType() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/generics/genericsInType.kt");
|
runTest("compiler/testData/diagnostics/tests/generics/genericsInType.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user