From eb8ce449e3621beaba409cad7c3596215bea6d89 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 22 Nov 2022 13:13:37 +0200 Subject: [PATCH] [FIR] Don't lose flexible types during capturing from expression --- ...CompilerTestFE10TestdataTestGenerated.java | 6 +++++ ...irOldFrontendDiagnosticsTestGenerated.java | 6 +++++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 +++++ .../jetbrains/kotlin/fir/types/TypeUtils.kt | 2 +- .../kotlin/fir/resolve/calls/Arguments.kt | 27 +++++++------------ .../platformSuperClass.fir.kt | 22 --------------- .../projectionsScope/platformSuperClass.kt | 1 + .../onlyInputTypesAndClassLiterals.fir.kt | 14 ++++++++++ .../onlyInputTypesAndClassLiterals.kt | 14 ++++++++++ .../onlyInputTypesAndClassLiterals.txt | 5 ++++ .../test/runners/DiagnosticTestGenerated.java | 6 +++++ 11 files changed, 69 insertions(+), 40 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/generics/projectionsScope/platformSuperClass.fir.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.fir.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.txt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index a952b2fcfe9..ad304ee9991 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -38439,6 +38439,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypes.kt"); } + @Test + @TestMetadata("onlyInputTypesAndClassLiterals.kt") + public void testOnlyInputTypesAndClassLiterals() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.kt"); + } + @Test @TestMetadata("onlyInputTypesAndLowPriority.kt") public void testOnlyInputTypesAndLowPriority() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 271fb55dab1..7dfc125fb2f 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -38439,6 +38439,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypes.kt"); } + @Test + @TestMetadata("onlyInputTypesAndClassLiterals.kt") + public void testOnlyInputTypesAndClassLiterals() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.kt"); + } + @Test @TestMetadata("onlyInputTypesAndLowPriority.kt") public void testOnlyInputTypesAndLowPriority() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index c7846237b0a..2355ee3d2ce 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -38439,6 +38439,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypes.kt"); } + @Test + @TestMetadata("onlyInputTypesAndClassLiterals.kt") + public void testOnlyInputTypesAndClassLiterals() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.kt"); + } + @Test @TestMetadata("onlyInputTypesAndLowPriority.kt") public void testOnlyInputTypesAndLowPriority() throws Exception { diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt index b199675c990..38e77efbaf9 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt @@ -348,7 +348,7 @@ fun FirDeclaration.visibilityForApproximation(container: FirDeclaration?): Visib } -internal fun ConeTypeContext.captureFromArgumentsInternal(type: ConeKotlinType, status: CaptureStatus): ConeKotlinType? { +fun ConeTypeContext.captureFromArgumentsInternal(type: ConeKotlinType, status: CaptureStatus): ConeKotlinType? { val capturedArguments = captureArguments(type, status) ?: return null return if (type is ConeFlexibleType) { ConeFlexibleType( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt index 3ac0ae906d1..0893f5b1e93 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt @@ -320,30 +320,23 @@ fun Candidate.prepareCapturedType(argumentType: ConeKotlinType, context: Resolut } private fun Candidate.captureTypeFromExpressionOrNull(argumentType: ConeKotlinType, context: ResolutionContext): ConeKotlinType? { - if (argumentType is ConeFlexibleType) { - return captureTypeFromExpressionOrNull(argumentType.lowerBound, context) - } - - if (argumentType is ConeIntersectionType) { - val intersectedTypes = argumentType.intersectedTypes.map { captureTypeFromExpressionOrNull(it, context) ?: it } - if (intersectedTypes == argumentType.intersectedTypes) return null + val type = argumentType.fullyExpandedType(context.session) + if (type is ConeIntersectionType) { + val intersectedTypes = type.intersectedTypes.map { captureTypeFromExpressionOrNull(it, context) ?: it } + if (intersectedTypes == type.intersectedTypes) return null return ConeIntersectionType( intersectedTypes, - argumentType.alternativeType?.let { captureTypeFromExpressionOrNull(it, context) ?: it } + type.alternativeType?.let { captureTypeFromExpressionOrNull(it, context) ?: it } ) } - if (argumentType !is ConeClassLikeType) return null + if (type !is ConeClassLikeType && type !is ConeFlexibleType) return null - argumentType.fullyExpandedType(context.session).let { - if (it !== argumentType) return captureTypeFromExpressionOrNull(it, context) - } + if (type.typeArguments.isEmpty()) return null - if (argumentType.typeArguments.isEmpty()) return null - - return context.session.typeContext.captureFromArguments( - argumentType, CaptureStatus.FROM_EXPRESSION - ) as? ConeKotlinType + return context.session.typeContext.captureFromArgumentsInternal( + type, CaptureStatus.FROM_EXPRESSION + ) } private fun checkApplicabilityForArgumentType( diff --git a/compiler/testData/diagnostics/tests/generics/projectionsScope/platformSuperClass.fir.kt b/compiler/testData/diagnostics/tests/generics/projectionsScope/platformSuperClass.fir.kt deleted file mode 100644 index 36cd2389afc..00000000000 --- a/compiler/testData/diagnostics/tests/generics/projectionsScope/platformSuperClass.fir.kt +++ /dev/null @@ -1,22 +0,0 @@ -// !CHECK_TYPE - -// FILE: Clazz.java -public class Clazz { - public T getT() { return null; } - public Clazz getSuperClass() { return null; } -} - -// FILE: main.kt -fun test(clazz: Clazz<*>) { - clazz.t checkType { _() } - clazz.getSuperClass() checkType { _?>() } - clazz.getSuperClass().t checkType { _() } - - clazz.superClass checkType { _?>() } - clazz.superClass.t checkType { _() } - - // See KT-9294 - if (clazz.superClass == null) { - throw NullPointerException() - } -} diff --git a/compiler/testData/diagnostics/tests/generics/projectionsScope/platformSuperClass.kt b/compiler/testData/diagnostics/tests/generics/projectionsScope/platformSuperClass.kt index 9762496f347..9f42a257292 100644 --- a/compiler/testData/diagnostics/tests/generics/projectionsScope/platformSuperClass.kt +++ b/compiler/testData/diagnostics/tests/generics/projectionsScope/platformSuperClass.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !CHECK_TYPE // FILE: Clazz.java diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.fir.kt new file mode 100644 index 00000000000..f9823c06fc1 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.fir.kt @@ -0,0 +1,14 @@ +// WITH_STDLIB +// WITH_REFLECT +// FULL_JDK +import java.lang.reflect.Field + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +fun <@kotlin.internal.OnlyInputTypes T> assertEquals(expected: T, actual: T): T = actual + +fun test(field: Field) { + ?")!>assertEquals( + ..java.lang.Class<*>?!")!>field.type, + ?")!>Long::class.javaPrimitiveType + ) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.kt new file mode 100644 index 00000000000..7450a3abf39 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.kt @@ -0,0 +1,14 @@ +// WITH_STDLIB +// WITH_REFLECT +// FULL_JDK +import java.lang.reflect.Field + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +fun <@kotlin.internal.OnlyInputTypes T> assertEquals(expected: T, actual: T): T = actual + +fun test(field: Field) { + ?")!>assertEquals( + ..java.lang.Class<*>?)")!>field.type, + ?")!>Long::class.javaPrimitiveType + ) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.txt b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.txt new file mode 100644 index 00000000000..2439003a677 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.txt @@ -0,0 +1,5 @@ +package + +@kotlin.Suppress(names = {"INVISIBLE_MEMBER", "INVISIBLE_REFERENCE"}) public fun assertEquals(/*0*/ expected: T, /*1*/ actual: T): T +public fun test(/*0*/ field: java.lang.reflect.Field): kotlin.Unit + diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 623d5e99b82..52b004e60cf 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -38529,6 +38529,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypes.kt"); } + @Test + @TestMetadata("onlyInputTypesAndClassLiterals.kt") + public void testOnlyInputTypesAndClassLiterals() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndClassLiterals.kt"); + } + @Test @TestMetadata("onlyInputTypesAndLowPriority.kt") public void testOnlyInputTypesAndLowPriority() throws Exception {