diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt index e75eb8e4ac8..6c365b65288 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt @@ -18,9 +18,11 @@ import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.ConeNullability.NOT_NULL import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.AbstractTypeChecker class SyntheticPropertySymbol( callableId: CallableId, @@ -72,8 +74,28 @@ class FirSyntheticPropertiesScope( val parameter = setter.valueParameters.singleOrNull() ?: return if (setter.typeParameters.isNotEmpty() || setter.isStatic) return val parameterType = (parameter.returnTypeRef as? FirResolvedTypeRef)?.type ?: return - if (getterReturnType.withNullability(NOT_NULL) != parameterType.withNullability(NOT_NULL)) { - return + if (getter.symbol.callableId.classId == setter.symbol.callableId.classId) { + if (getterReturnType.withNullability(NOT_NULL) != parameterType.withNullability(NOT_NULL)) { + return + } + } else { + // TODO: at this moment it works for cases like + // class Base { + // void setSomething(Object value) {} + // } + // class Derived extends Base { + // String getSomething() { return ""; } + // } + // In FE 1.0, we should have also Object getSomething() in class Base for this to work + // I think details here are worth designing + if (!AbstractTypeChecker.isSubtypeOf( + session.typeContext, + getterReturnType.withNullability(NOT_NULL), + parameterType.withNullability(NOT_NULL) + ) + ) { + return + } } matchingSetter = setter }) diff --git a/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/overrideOnlyGetter.kt b/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/overrideOnlyGetter.kt index bb86a09234a..b257e7ae6a0 100644 --- a/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/overrideOnlyGetter.kt +++ b/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/overrideOnlyGetter.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // FILE: JavaClass2.java class JavaClass1 { diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/OverrideGetterOnly.fir.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/OverrideGetterOnly.fir.kt index e0e96602473..77096c235da 100644 --- a/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/OverrideGetterOnly.fir.kt +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/OverrideGetterOnly.fir.kt @@ -5,7 +5,7 @@ fun foo(o: JavaClass2) { o.something = "" o.setSomething(1) o.something = 1 // we generate extension property for JavaClass2 with more specific type - o.something += "1" + o.something += "1" } fun useString(i: String) {} diff --git a/compiler/testData/ir/irText/firProblems/kt42496.fir.txt b/compiler/testData/ir/irText/firProblems/kt42496.fir.txt new file mode 100644 index 00000000000..98c8b0c2277 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/kt42496.fir.txt @@ -0,0 +1,11 @@ +FILE fqName: fileName:/kt42496.kt + FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + VAR name:javaClass type:.JavaClass2 [val] + CONSTRUCTOR_CALL 'public constructor () [primary] declared in .JavaClass2' type=.JavaClass2 origin=null + CALL 'public open fun setSomething (value: kotlin.Any?): kotlin.Unit declared in .JavaClass1' type=kotlin.Unit origin=EQ + $this: GET_VAR 'val javaClass: .JavaClass2 [val] declared in .box' type=.JavaClass2 origin=null + value: CONST String type=kotlin.String value="OK" + RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CALL 'public open fun getSomething (): kotlin.String? declared in .JavaClass2' type=kotlin.String? origin=GET_PROPERTY + $this: GET_VAR 'val javaClass: .JavaClass2 [val] declared in .box' type=.JavaClass2 origin=null