diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index 40b9da1cdfc..03118666b62 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -174,5 +174,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { ) override val valueParameterCheckers: Set - get() = setOf() + get() = setOf( + FirValueParameterDefaultValueTypeMismatchChecker, + ) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirValueParameterDefaultValueTypeMismatchChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirValueParameterDefaultValueTypeMismatchChecker.kt new file mode 100644 index 00000000000..57a956102e1 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirValueParameterDefaultValueTypeMismatchChecker.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.checkers.declaration + +import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.checkers.checkTypeMismatch +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.declarations.FirValueParameter +import org.jetbrains.kotlin.fir.types.coneType + +object FirValueParameterDefaultValueTypeMismatchChecker : FirValueParameterChecker() { + override fun check(declaration: FirValueParameter, context: CheckerContext, reporter: DiagnosticReporter) { + val defaultValue = declaration.defaultValue ?: return + val source = requireNotNull(declaration.source) + val parameterType = declaration.returnTypeRef.coneType + + checkTypeMismatch(parameterType, null, defaultValue, context, source, reporter, true) + } +} \ No newline at end of file diff --git a/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt b/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt index 91cbee61f7a..2ab47fbcb2a 100644 --- a/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt +++ b/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt @@ -945,11 +945,14 @@ object PositioningStrategies { val PROPERTY_INITIALIZER: PositioningStrategy = object : PositioningStrategy() { override fun mark(element: KtNamedDeclaration): List { - return markElement(when (element) { - is KtProperty -> element.initializer ?: element - is KtParameter -> element.typeReference ?: element - else -> element - }) + return markElement( + when (element) { + is KtProperty -> element.initializer ?: element + // Type reference is used as a target for loop variable type mismatches + is KtParameter -> element.defaultValue ?: element.typeReference ?: element + else -> element + } + ) } } diff --git a/compiler/testData/codegen/box/collectionLiterals/defaultAnnotationParameterValues.kt b/compiler/testData/codegen/box/collectionLiterals/defaultAnnotationParameterValues.kt index f361eb970c7..e926ab15d7f 100644 --- a/compiler/testData/codegen/box/collectionLiterals/defaultAnnotationParameterValues.kt +++ b/compiler/testData/codegen/box/collectionLiterals/defaultAnnotationParameterValues.kt @@ -19,6 +19,7 @@ annotation class Foo( val a: IntArray = [], val b: IntArray = [1, 2, 3], val c: Array = ["/"], + @Suppress("INITIALIZER_TYPE_MISMATCH") // Remove after KT-59581 is fixed val d: Array> = [Int::class, Array::class], val e: DoubleArray = [1.0] ) diff --git a/compiler/testData/diagnostics/tests/DefaultValuesTypechecking.fir.kt b/compiler/testData/diagnostics/tests/DefaultValuesTypechecking.fir.kt index 359e3ced476..1b132bd636a 100644 --- a/compiler/testData/diagnostics/tests/DefaultValuesTypechecking.fir.kt +++ b/compiler/testData/diagnostics/tests/DefaultValuesTypechecking.fir.kt @@ -1,6 +1,6 @@ val x = "" -fun bar(x : Int = "", y : Int = x, z : String = y) { +fun bar(x : Int = "", y : Int = x, z : String = y) { } @@ -8,7 +8,7 @@ fun bar(x : Int = "", y : Int = x, z : String = y) { class A(x : Int = y, y : Int = x) { // None of the references is resolved, no types checked constructor(x : Int = x) : this(x, x) - fun foo(bool: Boolean, a: Int = b, b: String = a) {} + fun foo(bool: Boolean, a: Int = b, b: String = a) {} } val z = 3 diff --git a/compiler/testData/diagnostics/tests/ObjectWithConstructor.fir.kt b/compiler/testData/diagnostics/tests/ObjectWithConstructor.fir.kt index af504b4e89b..eecd840b0cd 100644 --- a/compiler/testData/diagnostics/tests/ObjectWithConstructor.fir.kt +++ b/compiler/testData/diagnostics/tests/ObjectWithConstructor.fir.kt @@ -1,11 +1,11 @@ object A1() { - constructor(x: Int = "", y: Int) : this() { + constructor(x: Int = "", y: Int) : this() { x + y } } object A2 public constructor(private val prop: Int) { - constructor(x: Int = "", y: Int) : this(x * y) { + constructor(x: Int = "", y: Int) : this(x * y) { x + y } } diff --git a/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsWithVarargs.fir.kt b/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsWithVarargs.fir.kt index 195a73585a7..7a695277178 100644 --- a/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsWithVarargs.fir.kt +++ b/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsWithVarargs.fir.kt @@ -8,7 +8,7 @@ annotation class Ann4(vararg val a: String = ["/"]) annotation class Ann5(vararg val a: Ann4 = []) annotation class Ann6(vararg val a: Ann4 = [Ann4(*["a", "b"])]) -annotation class Ann7(vararg val a: Long = [1L, null, ""]) +annotation class Ann7(vararg val a: Long = [1L, null, ""]) @Ann1(*[]) fun test1_0() {} diff --git a/compiler/testData/diagnostics/tests/collectionLiterals/defaultValuesInAnnotation.fir.kt b/compiler/testData/diagnostics/tests/collectionLiterals/defaultValuesInAnnotation.fir.kt index 2defd97549b..bae77f603bf 100644 --- a/compiler/testData/diagnostics/tests/collectionLiterals/defaultValuesInAnnotation.fir.kt +++ b/compiler/testData/diagnostics/tests/collectionLiterals/defaultValuesInAnnotation.fir.kt @@ -5,9 +5,9 @@ annotation class Foo( ) annotation class Bar( - val a: Array = [' '], + val a: Array = [' '], val b: Array = ["", ''], - val c: Array = [1] + val c: Array = [1] ) annotation class Base( @@ -18,6 +18,6 @@ annotation class Base( ) annotation class Err( - val a: IntArray = [1L], - val b: Array = [1] + val a: IntArray = [1L], + val b: Array = [1] ) diff --git a/compiler/testData/diagnostics/tests/collectionLiterals/defaultValuesWithConstantsInAnnotation.fir.kt b/compiler/testData/diagnostics/tests/collectionLiterals/defaultValuesWithConstantsInAnnotation.fir.kt index 6112f79db2b..06164f377f7 100644 --- a/compiler/testData/diagnostics/tests/collectionLiterals/defaultValuesWithConstantsInAnnotation.fir.kt +++ b/compiler/testData/diagnostics/tests/collectionLiterals/defaultValuesWithConstantsInAnnotation.fir.kt @@ -17,7 +17,7 @@ annotation class Bar( ) annotation class Baz( - val a: IntArray = [null], - val b: IntArray = [1, null, 2], - val c: IntArray = [this] + val a: IntArray = [null], + val b: IntArray = [1, null, 2], + val c: IntArray = [this] ) diff --git a/compiler/testData/diagnostics/tests/modifiers/const/arrayInAnnotationArgumentType.fir.kt b/compiler/testData/diagnostics/tests/modifiers/const/arrayInAnnotationArgumentType.fir.kt index 328e56c4402..c3c3b9916a4 100644 --- a/compiler/testData/diagnostics/tests/modifiers/const/arrayInAnnotationArgumentType.fir.kt +++ b/compiler/testData/diagnostics/tests/modifiers/const/arrayInAnnotationArgumentType.fir.kt @@ -1,2 +1,2 @@ -annotation class A(val a: IntArray = arrayOf(1)) +annotation class A(val a: IntArray = arrayOf(1)) annotation class B(val a: IntArray = intArrayOf(1)) diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.fir.kt new file mode 100644 index 00000000000..5ecb7c5b663 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.fir.kt @@ -0,0 +1,88 @@ +// MODULE: m1-common +// FILE: common.kt + +import kotlin.reflect.KClass + +expect annotation class Primitives( + val z: Boolean = true, + val c: Char = 'c', + val b: Byte = 42.toByte(), + val s: Short = (-1).toShort(), + val i: Int = -42, + val f: Float = 2.72f, + val j: Long = 123456789123456789L, + val d: Double = 3.14159265358979 +) + +expect annotation class PrimitiveArrays( + val z: BooleanArray = [true], + val c: CharArray = ['c'], + val b: ByteArray = [42.toByte()], + val s: ShortArray = [(-1).toShort()], + val i: IntArray = [-42], + val f: FloatArray = [2.72f], + val j: LongArray = [123456789123456789L], + val d: DoubleArray = [3.14159265358979] +) + +enum class En { A, B } + +annotation class Anno(val value: String = "Anno") + +expect annotation class Classes( + val s: String = "OK", + val e: En = En.B, + // TODO: this does not work at the moment because AnnotationDescriptor subclasses do not implement equals correctly + // val a: Anno = Anno(), + val k: KClass<*> = List::class +) + +expect annotation class ClassArrays( + val s: Array = ["OK"], + val e: Array = [En.B], + // val a: Array = [Anno()], + val k: Array> = [List::class], // KT-59581 + vararg val v: Int = [42] +) + +// MODULE: m2-jvm()()(m1-common) +// FILE: jvm.kt + +import kotlin.reflect.KClass + +actual annotation class Primitives( + actual val z: Boolean = true, + actual val c: Char = 'c', + actual val b: Byte = 42.toByte(), + actual val s: Short = (-1).toShort(), + actual val i: Int = -42, + actual val f: Float = 2.72f, + actual val j: Long = 123456789123456789L, + actual val d: Double = 3.14159265358979 +) + +actual annotation class PrimitiveArrays( + actual val z: BooleanArray = [true], + actual val c: CharArray = ['c'], + actual val b: ByteArray = [42.toByte()], + actual val s: ShortArray = [(-1).toShort()], + actual val i: IntArray = [-42], + actual val f: FloatArray = [2.72f], + actual val j: LongArray = [123456789123456789L], + actual val d: DoubleArray = [3.14159265358979] +) + +actual annotation class Classes( + actual val s: String = "OK", + actual val e: En = En.B, + // actual val a: Anno = Anno(), + actual val k: KClass<*> = List::class +) + +actual annotation class ClassArrays( + actual val s: Array = ["OK"], + actual val e: Array = [En.B], + // actual val a: Array = [Anno()], + actual val k: Array> = [List::class], + actual vararg val v: Int = [42] +) diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.kt index 3fe9dc4930a..ec90c26cbd9 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // MODULE: m1-common // FILE: common.kt @@ -42,7 +41,7 @@ expect annotation class ClassArrays( val s: Array = ["OK"], val e: Array = [En.B], // val a: Array = [Anno()], - val k: Array> = [List::class], + val k: Array> = [List::class], // KT-59581 vararg val v: Int = [42] ) diff --git a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/defaultParameters.fir.kt b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/defaultParameters.fir.kt index 9c884b34a28..5a73a51460d 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/defaultParameters.fir.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/defaultParameters.fir.kt @@ -21,7 +21,7 @@ fun test() { // platform type with no annotation val platformJ = J.staticJ - fun foo(p: J = platformNN, p1: J = platformN, p2: J = platformJ) {} + fun foo(p: J = platformNN, p1: J = platformN, p2: J = platformJ) {} fun foo1(p: J? = platformNN, p1: J? = platformN, p2: J? = platformJ) {} } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superFunAccess.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superFunAccess.fir.kt index 1031447dae2..ddbcabbdc0d 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superFunAccess.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superFunAccess.fir.kt @@ -3,6 +3,6 @@ open class B(x: Int) { fun foo() = 1 } class A : B { - constructor(x: Int, y: Int = x + foo() + this.foo() + super.foo()) : + constructor(x: Int, y: Int = x + foo() + this.foo() + super.foo()) : super(x + foo() + this.foo() + super.foo()) } diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superFunAccessOverriden.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superFunAccessOverriden.fir.kt index 43e6380b81a..599982ac729 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superFunAccessOverriden.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superFunAccessOverriden.fir.kt @@ -4,6 +4,6 @@ open class B(x: Int) { } class A : B { override fun foo() = 2 - constructor(x: Int, y: Int = x + foo() + this.foo() + super.foo()) : + constructor(x: Int, y: Int = x + foo() + this.foo() + super.foo()) : super(x + foo() + this.foo() + super.foo()) } diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superPropertyAccess.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superPropertyAccess.fir.kt index dbfc4346104..d44bce3b7fa 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superPropertyAccess.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superPropertyAccess.fir.kt @@ -1,6 +1,6 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER open class B(val prop: Int) class A : B { - constructor(x: Int, y: Int = x + prop + this.prop + super.prop) : + constructor(x: Int, y: Int = x + prop + this.prop + super.prop) : super(x + prop + this.prop + super.prop) } diff --git a/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.1.fir.kt index 0e3a24eec72..9d9eaf06e05 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.1.fir.kt @@ -65,4 +65,4 @@ fun case_10(x: Int?) { } // TESTCASE NUMBER: 11 -fun case_11(x: Int?, y: Int = x) = null +fun case_11(x: Int?, y: Int = x) = null diff --git a/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.2.fir.kt index 8d43eef7069..964194db0c3 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.2.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.2.fir.kt @@ -11,29 +11,29 @@ */ // TESTCASE NUMBER: 1 -fun case_1(x: Int = null) { +fun case_1(x: Int = null) { println(x) } // TESTCASE NUMBER: 2 -fun case_2(x: Any = null) { +fun case_2(x: Any = null) { println(x) } // TESTCASE NUMBER: 3 -fun case_3(x: Nothing = null) { +fun case_3(x: Nothing = null) { println(x) } // TESTCASE NUMBER: 4 -class Case4(x: Int = null) +class Case4(x: Int = null) // TESTCASE NUMBER: 5 -class Case5 constructor(x: Any = null) +class Case5 constructor(x: Any = null) // TESTCASE NUMBER: 6 class Case6 { - fun foo(x: Nothing = null) {} + fun foo(x: Nothing = null) {} } // TESTCASE NUMBER: 7 diff --git a/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.3.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.3.fir.kt index 8129b33c32a..6bc3a711f15 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.3.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.3.fir.kt @@ -11,28 +11,28 @@ */ // TESTCASE NUMBER: 1 -fun case_1(x: T = null) { +fun case_1(x: T = null) { println(x) } // TESTCASE NUMBER: 2 -fun case_2(x: T = null) { +fun case_2(x: T = null) { println(x) } // TESTCASE NUMBER: 3 fun case_3() { - class Case4 (x: T = null) + class Case4 (x: T = null) } // TESTCASE NUMBER: 4 fun case_4() { - class Case4(x: T = null) + class Case4(x: T = null) } // TESTCASE NUMBER: 5 fun case_5(x: T) where T: Number?, K: Number { if (x == null) { - class Case5 constructor(y: K = x) + class Case5 constructor(y: K = x) } }