[FIR] NOTHING_TO_OVERRIDE diagnostic

This commit is contained in:
Andrey Zinovyev
2021-06-21 12:56:40 +03:00
committed by teamcityserver
parent 9452b788bf
commit b44785c24e
38 changed files with 99 additions and 250 deletions
@@ -19,13 +19,13 @@ fun test(z: Int, c: Char) {}
}<!> }<!>
<!REDECLARATION!>class B : <!FINAL_SUPERTYPE, SUPERTYPE_NOT_INITIALIZED!>A<!> { <!REDECLARATION!>class B : <!FINAL_SUPERTYPE, SUPERTYPE_NOT_INITIALIZED!>A<!> {
<!CONFLICTING_OVERLOADS!>override fun rest(s: String)<!> {} <!CONFLICTING_OVERLOADS!><!NOTHING_TO_OVERRIDE!>override<!> fun rest(s: String)<!> {}
<!CONFLICTING_OVERLOADS!>fun rest(s: String)<!> {} <!CONFLICTING_OVERLOADS!>fun rest(s: String)<!> {}
fun rest(l: Long) {} fun rest(l: Long) {}
override val u = 310 <!NOTHING_TO_OVERRIDE!>override<!> val u = 310
}<!> }<!>
<!REDECLARATION!>interface B<!> <!REDECLARATION!>interface B<!>
@@ -17,17 +17,17 @@ class CallBasedInExpressionGenerator(
private val resolvedCall = operatorReference.<!UNRESOLVED_REFERENCE!>getResolvedCallWithAssert<!>(codegen.<!UNRESOLVED_REFERENCE!>bindingContext<!>) private val resolvedCall = operatorReference.<!UNRESOLVED_REFERENCE!>getResolvedCallWithAssert<!>(codegen.<!UNRESOLVED_REFERENCE!>bindingContext<!>)
private val isInverted = operatorReference.<!UNRESOLVED_REFERENCE!>getReferencedNameElementType<!>() == <!UNRESOLVED_REFERENCE!>KtTokens<!>.NOT_IN private val isInverted = operatorReference.<!UNRESOLVED_REFERENCE!>getReferencedNameElementType<!>() == <!UNRESOLVED_REFERENCE!>KtTokens<!>.NOT_IN
override fun generate(argument: StackValue): BranchedValue = <!NOTHING_TO_OVERRIDE!>override<!> fun generate(argument: StackValue): BranchedValue =
gen(argument).let { if (isInverted) <!UNRESOLVED_REFERENCE!>Invert<!>(it) else it } gen(argument).let { if (isInverted) <!UNRESOLVED_REFERENCE!>Invert<!>(it) else it }
private fun gen(argument: StackValue): BranchedValue = private fun gen(argument: StackValue): BranchedValue =
object : BranchedValue(<!TOO_MANY_ARGUMENTS!>argument<!>, <!TOO_MANY_ARGUMENTS!>null<!>, <!TOO_MANY_ARGUMENTS!>argument.<!UNRESOLVED_REFERENCE!>type<!><!>, <!TOO_MANY_ARGUMENTS!><!UNRESOLVED_REFERENCE!>Opcodes<!>.IFEQ<!>) { object : BranchedValue(<!TOO_MANY_ARGUMENTS!>argument<!>, <!TOO_MANY_ARGUMENTS!>null<!>, <!TOO_MANY_ARGUMENTS!>argument.<!UNRESOLVED_REFERENCE!>type<!><!>, <!TOO_MANY_ARGUMENTS!><!UNRESOLVED_REFERENCE!>Opcodes<!>.IFEQ<!>) {
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) { <!NOTHING_TO_OVERRIDE!>override<!> fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
invokeFunction(v) invokeFunction(v)
<!UNRESOLVED_REFERENCE!>coerceTo<!>(type, kotlinType, v) <!UNRESOLVED_REFERENCE!>coerceTo<!>(type, kotlinType, v)
} }
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) { <!NOTHING_TO_OVERRIDE!>override<!> fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
invokeFunction(v) invokeFunction(v)
v.<!UNRESOLVED_REFERENCE!>visitJumpInsn<!>(if (jumpIfFalse) <!UNRESOLVED_REFERENCE!>Opcodes<!>.IFEQ else <!UNRESOLVED_REFERENCE!>Opcodes<!>.IFNE, jumpLabel) v.<!UNRESOLVED_REFERENCE!>visitJumpInsn<!>(if (jumpIfFalse) <!UNRESOLVED_REFERENCE!>Opcodes<!>.IFEQ else <!UNRESOLVED_REFERENCE!>Opcodes<!>.IFNE, jumpLabel)
} }
@@ -25,7 +25,7 @@ interface B {
interface Foo interface Foo
expect abstract class AbstractClass : Foo { expect abstract class AbstractClass : Foo {
abstract override fun foo() abstract <!NOTHING_TO_OVERRIDE!>override<!> fun foo()
abstract fun bar() abstract fun bar()
@@ -9,7 +9,7 @@ open class A {
class B : A() { class B : A() {
override fun foo(): B = this override fun foo(): B = this
fun <!VIRTUAL_MEMBER_HIDDEN!>bar<!>(): B = this // Missing 'override' fun <!VIRTUAL_MEMBER_HIDDEN!>bar<!>(): B = this // Missing 'override'
override fun buz(p: B): B = this //No override as B not :> A <!NOTHING_TO_OVERRIDE!>override<!> fun buz(p: B): B = this //No override as B not :> A
fun test() { fun test() {
foo() foo()
@@ -6,8 +6,8 @@ public interface JA<E> {
// FILE: main.kt // FILE: main.kt
interface KB<F> { interface KB<F> {
override fun getFoo(): F <!NOTHING_TO_OVERRIDE!>override<!> fun getFoo(): F
override fun getBar(): F <!NOTHING_TO_OVERRIDE!>override<!> fun getBar(): F
} }
interface D1 : JA<String>, KB<String> interface D1 : JA<String>, KB<String>
@@ -250,10 +250,8 @@ object FirOverrideChecker : FirClassChecker() {
} }
} }
@Suppress("UNUSED_PARAMETER") // TODO: delete me after implementing body
private fun DiagnosticReporter.reportNothingToOverride(declaration: FirMemberDeclaration, context: CheckerContext) { private fun DiagnosticReporter.reportNothingToOverride(declaration: FirMemberDeclaration, context: CheckerContext) {
// TODO: not ready yet, e.g., Collections reportOn(declaration.source, FirErrors.NOTHING_TO_OVERRIDE, declaration, context)
// reportOn(declaration.source, FirErrors.NOTHING_TO_OVERRIDE, declaration, context)
} }
private fun DiagnosticReporter.reportOverridingFinalMember( private fun DiagnosticReporter.reportOverridingFinalMember(
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.utils.isFinal import org.jetbrains.kotlin.fir.declarations.utils.isFinal
import org.jetbrains.kotlin.fir.dispatchReceiverTypeOrNull import org.jetbrains.kotlin.fir.dispatchReceiverTypeOrNull
import org.jetbrains.kotlin.fir.originalOrSelf import org.jetbrains.kotlin.fir.originalOrSelf
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
@@ -67,7 +68,16 @@ object FirJvmOverridesBackwardCompatibilityHelper : FirOverridesBackwardCompatib
if (originalMember.origin !in javaOrigin) return false if (originalMember.origin !in javaOrigin) return false
val containingClassName = originalMember.containingClass()?.classId?.asSingleFqName()?.toUnsafe() ?: return false val containingClassName = originalMember.containingClass()?.classId?.asSingleFqName()?.toUnsafe() ?: return false
// If the super class is mapped to a Kotlin built-in class, then we don't require `override` keyword. // If the super class is mapped to a Kotlin built-in class, then we don't require `override` keyword.
if (JavaToKotlinClassMap.mapKotlinToJava(containingClassName) != null) return true if (JavaToKotlinClassMap.mapKotlinToJava(containingClassName) != null) {
return true
}
if (!originalMember.isAbstract) {
val containingClass = originalMember.containingClass()?.toFirRegularClass(context.session)
if (containingClass?.isInterface == false) {
return false
}
}
val scope = val scope =
symbol.dispatchReceiverTypeOrNull()?.toRegularClass(context.session)?.unsubstitutedScope(context) ?: return false symbol.dispatchReceiverTypeOrNull()?.toRegularClass(context.session)?.unsubstitutedScope(context) ?: return false
@@ -58,9 +58,19 @@ class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractO
fun isEqualTypes(candidateTypeRef: FirTypeRef, baseTypeRef: FirTypeRef, substitutor: ConeSubstitutor): Boolean { fun isEqualTypes(candidateTypeRef: FirTypeRef, baseTypeRef: FirTypeRef, substitutor: ConeSubstitutor): Boolean {
candidateTypeRef.ensureResolvedTypeDeclaration(session, requiredPhase = FirResolvePhase.TYPES) candidateTypeRef.ensureResolvedTypeDeclaration(session, requiredPhase = FirResolvePhase.TYPES)
baseTypeRef.ensureResolvedTypeDeclaration(session, requiredPhase = FirResolvePhase.TYPES) baseTypeRef.ensureResolvedTypeDeclaration(session, requiredPhase = FirResolvePhase.TYPES)
if (candidateTypeRef is FirErrorTypeRef && baseTypeRef is FirErrorTypeRef) {
return maybeEqualErrorTypes(candidateTypeRef, baseTypeRef)
}
return isEqualTypes(candidateTypeRef.coneType, baseTypeRef.coneType, substitutor) return isEqualTypes(candidateTypeRef.coneType, baseTypeRef.coneType, substitutor)
} }
private fun maybeEqualErrorTypes(ref1: FirErrorTypeRef, ref2: FirErrorTypeRef): Boolean {
val delegated1 = ref1.delegatedTypeRef as? FirUserTypeRef ?: return false
val delegated2 = ref2.delegatedTypeRef as? FirUserTypeRef ?: return false
if (delegated1.qualifier.size != delegated2.qualifier.size) return false
return delegated1.qualifier.zip(delegated2.qualifier).all { (l, r) -> l.name == r.name }
}
/** /**
* Good case complexity is O(1) * Good case complexity is O(1)
@@ -11,5 +11,5 @@ open class B1 {
} }
class D1 : B1() { class D1 : B1() {
override fun foo() {} <!NOTHING_TO_OVERRIDE!>override<!> fun foo() {}
} }
@@ -1,25 +0,0 @@
// KT-11306 ABSTRACT_MEMBER_NOT_IMPLEMENTED for data class should inheriting interfaces requiring equals(), hashCode(), or toString()
interface Foo {
override fun equals(other: Any?): Boolean
override fun hashCode(): Int
override fun toString(): String
}
data class FooImpl(val num: Int) : Foo
data class FooImplSome(val num: Int) : Foo {
override fun hashCode() = 42
}
data class FooImplAll(val num: Int) : Foo {
override fun equals(other: Any?) = false
override fun hashCode() = 42
override fun toString() = "OK"
}
data class WrongSignatures(val num: Int) : Foo {
override fun equals(other: WrongSignatures) = false
override fun hashCode(): <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>Boolean<!> = true
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// KT-11306 ABSTRACT_MEMBER_NOT_IMPLEMENTED for data class should inheriting interfaces requiring equals(), hashCode(), or toString() // KT-11306 ABSTRACT_MEMBER_NOT_IMPLEMENTED for data class should inheriting interfaces requiring equals(), hashCode(), or toString()
interface Foo { interface Foo {
@@ -1,11 +0,0 @@
interface A {
fun visit(a:Int, b:String="") : String = b + a
}
class B : A {
override fun visit(a:Int, b:String) : String = b + a
}
class C : A {
override fun visit(a:Int) : String = "" + a
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
interface A { interface A {
fun visit(a:Int, b:String="") : String = b + a fun visit(a:Int, b:String="") : String = b + a
} }
@@ -3,5 +3,5 @@ interface B {
} }
class C : B { class C : B {
override val x = 1 <!NOTHING_TO_OVERRIDE!>override<!> val x = 1
} }
@@ -5,10 +5,10 @@ interface A<T> {
fun bar(x: T!!): T!! fun bar(x: T!!): T!!
} }
interface B<T1> : A<T1> { //interface B<T1> : A<T1> {
override fun foo(x: T1): T1 // override fun foo(x: T1): T1
override fun bar(x: T1!!): T1!! // override fun bar(x: T1!!): T1!!
} //}
interface C<T2> : A<T2> { interface C<T2> : A<T2> {
override fun foo(x: T2!!): T2!! override fun foo(x: T2!!): T2!!
@@ -17,7 +17,7 @@ interface C<T2> : A<T2> {
interface D : A<String?> { interface D : A<String?> {
override fun foo(x: String?): String? override fun foo(x: String?): String?
override fun bar(x: String): String <!NOTHING_TO_OVERRIDE!>override<!> fun bar(x: String): String
} }
interface E : A<String> { interface E : A<String> {
@@ -26,7 +26,7 @@ interface E : A<String> {
} }
interface F : A<String?> { interface F : A<String?> {
override fun foo(x: String): String <!NOTHING_TO_OVERRIDE!>override<!> fun foo(x: String): String
override fun bar(x: String?): String? override fun bar(x: String?): String?
} }
@@ -32,8 +32,8 @@ interface E : A<String> {
} }
interface F : A<String?> { interface F : A<String?> {
override fun foo(x: String): String <!NOTHING_TO_OVERRIDE!>override<!> fun foo(x: String): String
override fun bar(x: String?): String? <!NOTHING_TO_OVERRIDE!>override<!> fun bar(x: String?): String?
} }
interface G<T3 : Any> : A<T3> { interface G<T3 : Any> : A<T3> {
+1 -1
View File
@@ -11,7 +11,7 @@ abstract class A<T> {
// while for being a correct override it should be A<A<T>.B<S>>.B<A<T>.B<S>.C<U>> // while for being a correct override it should be A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>
// It happens because at the beginning we search implicit arguments for an outer classes through supertypes // It happens because at the beginning we search implicit arguments for an outer classes through supertypes
// See TypeResolver.computeImplicitOuterClassArguments for clarifications // See TypeResolver.computeImplicitOuterClassArguments for clarifications
override fun foo(x: B<C<U>>) { <!NOTHING_TO_OVERRIDE!>override<!> fun foo(x: B<C<U>>) {
throw UnsupportedOperationException() throw UnsupportedOperationException()
} }
@@ -0,0 +1,30 @@
// fir reports NOTHING_TO_OVERRIDE because it keeps only one definition of p.Base
// MODULE: m1
// FILE: x.kt
package p
public interface Base {
public fun <T> foo(t: Array<T>) {}
}
public interface A : Base
// MODULE: m2
// FILE: x.kt
package p
public interface Base {
public fun <T: Base> foo(t: Array<T>) {}
}
public interface B : Base
// MODULE: m3(m1, m2)
// FILE: x.kt
import p.*
class Foo: A, B {
override fun <T> foo(t: Array<T>) {}
<!NOTHING_TO_OVERRIDE!>override<!> fun <T: Base> foo(t: Array<T>) {}
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// MODULE: m1 // MODULE: m1
// FILE: x.kt // FILE: x.kt
package p package p
@@ -27,4 +26,4 @@ import p.*
class Foo: A, B { class Foo: A, B {
override fun <T> foo(t: Array<T>) {} override fun <T> foo(t: Array<T>) {}
override fun <T: Base> foo(t: Array<T>) {} override fun <T: Base> foo(t: Array<T>) {}
} }
@@ -42,8 +42,8 @@ abstract class MyAbstractClass1 : MyTrait<Int>, MyAbstractClass<String>() {
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class MyIllegalGenericClass1<!><T> : MyTrait<T>, MyAbstractClass<T>() {} <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class MyIllegalGenericClass1<!><T> : MyTrait<T>, MyAbstractClass<T>() {}
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class MyIllegalGenericClass2<!><T, R>(r : R) : MyTrait<T>, MyAbstractClass<R>() { <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class MyIllegalGenericClass2<!><T, R>(r : R) : MyTrait<T>, MyAbstractClass<R>() {
override fun foo(r: R) = r <!NOTHING_TO_OVERRIDE!>override<!> fun foo(r: R) = r
override val <<!TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER!>T<!>> pr : R = r <!NOTHING_TO_OVERRIDE!>override<!> val <<!TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER!>T<!>> pr : R = r
} }
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class MyIllegalClass1<!> : MyTrait<Int>, MyAbstractClass<String>() {} <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class MyIllegalClass1<!> : MyTrait<Int>, MyAbstractClass<String>() {}
abstract class MyLegalAbstractClass1 : MyTrait<Int>, MyAbstractClass<String>() {} abstract class MyLegalAbstractClass1 : MyTrait<Int>, MyAbstractClass<String>() {}
@@ -38,8 +38,8 @@ class MyChildClass() : MyClass() {}
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class MyIllegalClass4<!>() : MyTrait, MyAbstractClass() { <!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class MyIllegalClass4<!>() : MyTrait, MyAbstractClass() {
fun <!VIRTUAL_MEMBER_HIDDEN!>foo<!>() {} fun <!VIRTUAL_MEMBER_HIDDEN!>foo<!>() {}
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val <!VIRTUAL_MEMBER_HIDDEN!>pr<!> : Unit<!> <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val <!VIRTUAL_MEMBER_HIDDEN!>pr<!> : Unit<!>
override fun other() {} <!NOTHING_TO_OVERRIDE!>override<!> fun other() {}
override val otherPr : Int = 1 <!NOTHING_TO_OVERRIDE!>override<!> val otherPr : Int = 1
} }
class MyChildClass1() : MyClass() { class MyChildClass1() : MyClass() {
@@ -1,7 +0,0 @@
interface A {
fun <T> foo() where T : Any, T : Cloneable?
}
interface B : A {
override fun <T> foo() where T : Any?, T : Cloneable
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
interface A { interface A {
fun <T> foo() where T : Any, T : Cloneable? fun <T> foo() where T : Any, T : Cloneable?
} }
@@ -1,41 +0,0 @@
// FILE: A.java
import java.util.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class A<T> {
public void bar(@NotNull T x) {
}
}
// FILE: B1.java
public class B1 extends A<String> {
// real override
public void bar(String x) {
}
}
// FILE: B2.java
public class B2 extends A<String> {
// fake override bar
}
// FILE: k.kt
class C1 : A<String?>() {
override fun bar(x: String) {}
}
class C2 : A<String?>() {
override fun bar(x: String?) {}
}
fun test() {
B1().bar(<!NULL_FOR_NONNULL_TYPE!>null<!>)
B2().bar(<!NULL_FOR_NONNULL_TYPE!>null<!>)
C1().bar(<!NULL_FOR_NONNULL_TYPE!>null<!>)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: A.java // FILE: A.java
import java.util.*; import java.util.*;
@@ -1,41 +0,0 @@
// FILE: A.java
import java.util.*;
public interface A<T> {
<E extends CharSequence> E foo(T x, List<? extends T> y);
}
// FILE: B.java
import java.util.*;
public interface B extends A {
@Override
public String foo(Object x, List y);
}
// FILE: C.java
import java.util.*;
public abstract class C {
<E extends CharSequence, F extends E> E bar(F x, List<Map<E, F>> y);
}
// FILE: D.java
import java.util.*;
public class D extends C {
@Override
public String bar(CharSequence x, List y) {
return null;
}
}
// FILE: main.kt
class E : D(), B {
override fun foo(x: Any, y: List<Any?>): String = ""
override fun bar(x: CharSequence?, y: List<*>?): String = ""
}
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class E2<!> : B {
override fun foo(x: Any, y: List<String?>): String = ""
}
class F : D()
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: A.java // FILE: A.java
import java.util.*; import java.util.*;
public interface A<T> { public interface A<T> {
@@ -1,41 +0,0 @@
// (failed) attempt to reproduce exception in
// http://stackoverflow.com/questions/42571812/unsupportedoperationexception-while-building-a-kotlin-project-in-idea
// FILE: Fun.java
public interface Fun<T> {
public void invoke(T x);
}
// FILE: A.java
public interface A<T> {
public void foo(T x, Fun<? extends T> y);
}
// FILE: B.java
public interface B extends A {
@Override
public void foo(Object x, Fun y);
}
// FILE: C.java
public abstract class C {
public abstract <T> void bar(Fun<T> y);
public static <T> void aStaticMethod(T x, Fun<T> y) {}
public static abstract class D extends C {
@Override
public <T> void bar(Fun<T> y) {}
public static void aStaticMethod(Object x, Fun y) {}
}
}
// FILE: main.kt
class E1 : C.D(), B {
override fun foo(x: Any, y: Fun<Any?>) {}
}
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class E2<!> : B {
override fun foo(x: Any, y: Fun<String?>) {}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// (failed) attempt to reproduce exception in // (failed) attempt to reproduce exception in
// http://stackoverflow.com/questions/42571812/unsupportedoperationexception-while-building-a-kotlin-project-in-idea // http://stackoverflow.com/questions/42571812/unsupportedoperationexception-while-building-a-kotlin-project-in-idea
@@ -18,21 +18,21 @@ public class RawADerived extends A {
import java.util.*; import java.util.*;
class B1 : RawADerived() { class B1 : RawADerived() {
override fun foo(x: CharSequence, y: Map<Any?, Any?>, z: HashMap<Any, Any>): A<*> = null!! <!NOTHING_TO_OVERRIDE!>override<!> fun foo(x: CharSequence, y: Map<Any?, Any?>, z: HashMap<Any, Any>): A<*> = null!!
override fun bar(d: Array<Array<List<*>>>) {} <!NOTHING_TO_OVERRIDE!>override<!> fun bar(d: Array<Array<List<*>>>) {}
} }
class B2 : RawADerived() { class B2 : RawADerived() {
override fun foo(x: CharSequence?, y: MutableMap<Any?, Any?>, z: HashMap<Any?, Any?>): A<String> = null!! <!NOTHING_TO_OVERRIDE!>override<!> fun foo(x: CharSequence?, y: MutableMap<Any?, Any?>, z: HashMap<Any?, Any?>): A<String> = null!!
override fun bar(d: Array<Array<MutableList<*>>>) {} <!NOTHING_TO_OVERRIDE!>override<!> fun bar(d: Array<Array<MutableList<*>>>) {}
} }
class B3 : RawADerived() { class B3 : RawADerived() {
// Type of second parameter (y) is not equal to overridden // Type of second parameter (y) is not equal to overridden
// RawADerived.foo.y --- (MutableMap<Any?, Any?>..Map<out Any?, out Any?>) is not a subtype of Map<Any?, Any> // RawADerived.foo.y --- (MutableMap<Any?, Any?>..Map<out Any?, out Any?>) is not a subtype of Map<Any?, Any>
override fun foo(x: CharSequence, y: Map<Any?, Any>, z: HashMap<Any, Any>): A<*> = null!! <!NOTHING_TO_OVERRIDE!>override<!> fun foo(x: CharSequence, y: Map<Any?, Any>, z: HashMap<Any, Any>): A<*> = null!!
} }
class B4 : RawADerived() { class B4 : RawADerived() {
@@ -1,43 +0,0 @@
// FILE: A.java
import org.jetbrains.annotations.*;
public interface A<T> {
void foo(@NotNull T x, @Nullable T y);
}
// FILE: B1.java
// contains fake_override fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: kotlin.String, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.String?)
public interface B1 extends A<String> {}
// FILE: B2.java
import org.jetbrains.annotations.*;
public interface B2 extends A<String> {
// Ok, consistent override
// override fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: kotlin.String, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.String?)
void foo(@NotNull String x, @Nullable String y);
}
// FILE: B3.java
import org.jetbrains.annotations.*;
public interface B3 extends A<String> {
// inconsistent override, both parameters are platform
// override /*1*/ fun foo(/*0*/ org.jetbrains.annotations.Nullable() x: kotlin.String!, /*1*/ org.jetbrains.annotations.NotNull() y: kotlin.String!): kotlin.Unit
void foo(@Nullable String x, @NotNull String y);
}
// FILE: main.kt
// fake_override fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: kotlin.String, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.String?): kotlin.Unit
interface C1 : A<String>
// fake_override fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: kotlin.String?, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.String?): kotlin.Unit
interface C2 : A<String?>
interface C3 : B1 {
// inconsistent override
override fun foo(x: String?, y: String?);
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: A.java // FILE: A.java
import org.jetbrains.annotations.*; import org.jetbrains.annotations.*;
@@ -18,7 +18,7 @@ open class D {
} }
class E : D() { class E : D() {
internal override fun self() = this internal <!NOTHING_TO_OVERRIDE!>override<!> fun self() = this
fun test() { fun test() {
val s : E = self() val s : E = self()
@@ -11,7 +11,7 @@ abstract class MyIt2<out T> : Iterator<T> {
} }
abstract class MyIt3<out T> : Iterator<T> { abstract class MyIt3<out T> : Iterator<T> {
override fun forEachRemaining(x: Consumer<in T>?) {} <!NOTHING_TO_OVERRIDE!>override<!> fun forEachRemaining(x: Consumer<in T>?) {}
} }
abstract class MyIt4 : Iterator<String?> { abstract class MyIt4 : Iterator<String?> {
@@ -23,7 +23,7 @@ abstract class MyIt5 : Iterator<String> {
} }
abstract class MyIt6 : Iterator<String?> { abstract class MyIt6 : Iterator<String?> {
override fun forEachRemaining(x: Consumer<in String>) {} <!NOTHING_TO_OVERRIDE!>override<!> fun forEachRemaining(x: Consumer<in String>) {}
} }
abstract class MyIt7 : Iterator<String> { abstract class MyIt7 : Iterator<String> {
@@ -3,7 +3,7 @@
interface A : MutableCollection<String> { interface A : MutableCollection<String> {
// Override of deprecated function could be marked as deprecated too // Override of deprecated function could be marked as deprecated too
override fun nonExistingMethod(x: String) = "" <!NOTHING_TO_OVERRIDE!>override<!> fun nonExistingMethod(x: String) = ""
} }
fun foo(x: MutableCollection<Int>, y: Collection<String>, z: A) { fun foo(x: MutableCollection<Int>, y: Collection<String>, z: A) {
@@ -2,7 +2,7 @@
abstract class A : MutableList<String> { abstract class A : MutableList<String> {
override fun sort(/*0*/ p0: java.util.Comparator<in String>) { override fun sort(/*0*/ p0: java.util.Comparator<in String>) {
super.<!UNRESOLVED_REFERENCE!>sort<!>(p0) super.sort(p0)
} }
} }
+3
View File
@@ -1,4 +1,5 @@
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR
// SKIP_KT_DUMP // SKIP_KT_DUMP
// DUMP_EXTERNAL_CLASS: X // DUMP_EXTERNAL_CLASS: X
// DUMP_EXTERNAL_CLASS: AX // DUMP_EXTERNAL_CLASS: AX
@@ -8,6 +9,8 @@ abstract class A {
abstract val a: A? abstract val a: A?
} }
//Fir doesn't treat B.getA as an override, because it is not return-type compatible with AX.getA
// Which might be correct behaivour. So disable fir till KT-46042
class B() : AX() { class B() : AX() {
override fun getA(): X? = super.a override fun getA(): X? = super.a
} }
@@ -98,7 +98,8 @@ object JvmBuiltInsSignatures {
inJavaUtil( inJavaUtil(
"List", "List",
"replaceAll(Ljava/util/function/UnaryOperator;)V" "replaceAll(Ljava/util/function/UnaryOperator;)V",
"sort(Ljava/util/Comparator;)V"
) + ) +
inJavaUtil( inJavaUtil(