[FIR] KT-55552: Report type mismatch for delegated properties

^KT-55552 Fixed
This commit is contained in:
Nikolay Lunyak
2023-05-12 14:05:57 +03:00
committed by Space Team
parent 81d955a712
commit f94c795b5b
7 changed files with 49 additions and 32 deletions
@@ -120,6 +120,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirValueClassDeclarationChecker,
FirOuterClassArgumentsRequiredChecker,
FirPropertyInitializationChecker,
FirDelegateFieldTypeMismatchChecker,
)
override val constructorCheckers: Set<FirConstructorChecker>
@@ -0,0 +1,45 @@
/*
* 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.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.delegateFieldsMap
import org.jetbrains.kotlin.fir.expressions.FirCall
import org.jetbrains.kotlin.fir.expressions.calleeReference
import org.jetbrains.kotlin.fir.references.isError
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isSubtypeOf
object FirDelegateFieldTypeMismatchChecker : FirRegularClassChecker() {
@SymbolInternals
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
for (it in declaration.superTypeRefs.indices) {
val supertype = declaration.superTypeRefs[it]
val field = declaration.delegateFieldsMap?.get(it)?.fir ?: continue
val initializer = field.initializer ?: continue
val isReportedByErrorNodeDiagnosticCollector = initializer is FirCall && initializer.calleeReference?.isError() == true
if (
!isReportedByErrorNodeDiagnosticCollector &&
!initializer.typeRef.coneType.isSubtypeOf(supertype.coneType, context.session, true)
) {
reporter.reportOn(
initializer.source,
FirErrors.TYPE_MISMATCH,
field.returnTypeRef.coneType,
initializer.typeRef.coneType,
false,
context,
)
}
}
}
}
@@ -1,13 +0,0 @@
// ISSUE: KT-55552
interface B2 {
fun d()
}
class B
open class C(b: B) : B2 by b {} //no error in K2, K1 - [TYPE_MISMATCH] Type mismatch: inferred type is B but B2 was expected
fun main() {
val c = C(B()).d() //runtime AbstractMethodError
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// ISSUE: KT-55552
interface B2 {
@@ -1,18 +0,0 @@
// FILE: J.java
import org.jetbrains.annotations.*;
import java.util.*;
public class J {
@NotNull
public static List<String> staticNN;
@Nullable
public static List<String> staticN;
public static List<String> staticJ;
}
// FILE: k.kt
class A : List<String> by J.staticNN
class B : List<String> by J.staticN
class C : List<String> by J.staticJ
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: J.java
import org.jetbrains.annotations.*;
@@ -25,7 +25,7 @@ class Case4(val y: Any?): ClassWithCostructorParam(y!!) {
}
// TESTCASE NUMBER: 5
class Case5(val y: Any?): ClassWithCostructorParam(y as Interface1), Interface1 by y {}
class Case5(val y: Any?): ClassWithCostructorParam(y as Interface1), Interface1 by <!TYPE_MISMATCH!>y<!> {}
// TESTCASE NUMBER: 6
fun case_6(a: Int?) = object : ClassWithCostructorParam(a!!) {