[FIR] Don't lose flexible types during capturing from expression
This commit is contained in:
committed by
Space Team
parent
06e88b559a
commit
eb8ce449e3
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
// !CHECK_TYPE
|
||||
|
||||
// FILE: Clazz.java
|
||||
public class Clazz<T> {
|
||||
public T getT() { return null; }
|
||||
public Clazz<? super T> getSuperClass() { return null; }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
fun test(clazz: Clazz<*>) {
|
||||
clazz.t checkType { _<Any?>() }
|
||||
clazz.getSuperClass() checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Clazz<*>?>() }
|
||||
clazz.getSuperClass().t checkType { _<Any?>() }
|
||||
|
||||
clazz.superClass checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Clazz<*>?>() }
|
||||
clazz.superClass.t checkType { _<Any?>() }
|
||||
|
||||
// See KT-9294
|
||||
if (clazz.superClass == null) {
|
||||
throw NullPointerException()
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !CHECK_TYPE
|
||||
|
||||
// FILE: Clazz.java
|
||||
|
||||
+14
@@ -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) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("java.lang.Class<out kotlin.Any>?")!>assertEquals(
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("java.lang.Class<*>..java.lang.Class<*>?!")!>field.type<!>,
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("java.lang.Class<kotlin.Long>?")!>Long::class.javaPrimitiveType<!>
|
||||
)<!>
|
||||
}
|
||||
+14
@@ -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) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("java.lang.Class<out kotlin.Any>?")!>assertEquals(
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("(java.lang.Class<*>..java.lang.Class<*>?)")!>field.type<!>,
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("java.lang.Class<kotlin.Long>?")!>Long::class.javaPrimitiveType<!>
|
||||
)<!>
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package
|
||||
|
||||
@kotlin.Suppress(names = {"INVISIBLE_MEMBER", "INVISIBLE_REFERENCE"}) public fun </*0*/ @kotlin.internal.OnlyInputTypes T> assertEquals(/*0*/ expected: T, /*1*/ actual: T): T
|
||||
public fun test(/*0*/ field: java.lang.reflect.Field): kotlin.Unit
|
||||
|
||||
Generated
+6
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user