PSI2IR/FIR2IR: do not approximate T!! before translation

This leads to weird effects when it's in a contravariant position,
because it's approximated by Nothing.
This commit is contained in:
pyos
2021-05-10 13:12:02 +02:00
committed by teamcityserver
parent a37db99841
commit d5d6736e67
7 changed files with 35 additions and 22 deletions
@@ -67,6 +67,14 @@ class Fir2IrTypeConverter(
private val typeApproximator = ConeTypeApproximator(session.typeContext, session.languageVersionSettings)
private val typeApproximatorConfiguration =
object : TypeApproximatorConfiguration.AllFlexibleSameValue() {
override val allFlexible: Boolean get() = true
override val errorType: Boolean get() = true
override val integerLiteralType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true
}
fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType {
capturedTypeCache.clear()
return when (this) {
@@ -232,11 +240,9 @@ class Fir2IrTypeConverter(
} else null
}
}
val typeWithSpecifiedIntersectionTypes = substitutor.substituteOrSelf(type)
return typeApproximator.approximateToSuperType(
typeWithSpecifiedIntersectionTypes,
TypeApproximatorConfiguration.PublicDeclaration
) ?: type
return substitutor.substituteOrSelf(type).let {
typeApproximator.approximateToSuperType(it, typeApproximatorConfiguration) ?: it
}
}
}
@@ -8,9 +8,7 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.types.CommonSupertypes
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeApproximator
import org.jetbrains.kotlin.types.*
class TypeTranslatorImpl(
symbolTable: ReferenceSymbolTable,
@@ -25,8 +23,18 @@ class TypeTranslatorImpl(
private val typeApproximatorForNI = TypeApproximator(moduleDescriptor.builtIns, languageVersionSettings)
private val typeApproximatorConfiguration =
object : TypeApproximatorConfiguration.AllFlexibleSameValue() {
override val allFlexible: Boolean get() = true
override val errorType: Boolean get() = true
override val integerLiteralType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true
}
override fun approximateType(type: KotlinType): KotlinType =
typeApproximatorForNI.approximateDeclarationType(type, local = false)
substituteAlternativesInPublicType(type).let {
typeApproximatorForNI.approximateToSuperType(it, typeApproximatorConfiguration) ?: it
}
override fun commonSupertype(types: Collection<KotlinType>): KotlinType =
CommonSupertypes.commonSupertype(types)
@@ -1,11 +1,7 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_FIR: JVM_IR
// DONT_TARGET_EXACT_BACKEND: WASM
// WASM_MUTE_REASON: CALLABLE_REFERENCES_FAIL
fun <T> id(x: T): T = x
fun <T> String.extId(x: T): T = x
fun <T> foo(value: T?): T? = value?.let(::id) // KFunction1<Nothing, T>
fun <T> foo(value: T?): T? = value?.let(::id) // ::id = KFunction1<T!!, T!!>
fun <T> bar(value: T?): T? = value?.let(""::extId)
fun box() = foo("O")!! + foo("K")!!
fun box() = foo("O")!! + bar("K")!!
@@ -1,13 +1,11 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_FIR: JVM_IR
// DONT_TARGET_EXACT_BACKEND: WASM
// WASM_MUTE_REASON: CALLABLE_REFERENCES_FAIL
// WASM_MUTE_REASON: BINDING_RECEIVERS
fun <T> id(x: T): T = x
fun <T> String.extId(x: T): T = x
fun <T, R> T.myLet(block: (T) -> R): R = block(this)
fun <T> foo(value: T?): T? = value?.myLet(::id) // KFunction1<Nothing, T>
fun <T> foo(value: T?): T? = value?.myLet(::id) // ::id = KFunction1<T!!, T!!>
fun <T> bar(value: T?): T? = value?.myLet(""::extId)
fun box() = foo("O")!! + foo("K")!!
fun box() = foo("O")!! + bar("K")!!
@@ -12,7 +12,7 @@ fun <S : Any?> select(x: S, y: S): S {
}
fun <T : Any?> foo(a: Array<In<T>>, b: Array<In<String>>): Boolean {
return select<Array<out In<Nothing>>>(x = a, y = b).get(index = 0).ofType<Any?>(y = true)
return select<Array<out In<Nothing>>>(x = a, y = b).get(index = 0).ofType<Any>(y = true)
}
inline fun <reified K : Any?> In<K>.ofType(y: Any?): Boolean {
+1 -1
View File
@@ -33,7 +33,7 @@ FILE fqName:<root> fileName:/intersectionType1_NI.kt
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun foo <T> (a: kotlin.Array<<root>.In<T of <root>.foo>>, b: kotlin.Array<<root>.In<kotlin.String>>): kotlin.Boolean declared in <root>'
CALL 'public final fun ofType <K> (y: kotlin.Any?): kotlin.Boolean [inline] declared in <root>' type=kotlin.Boolean origin=null
<K>: kotlin.Any?
<K>: kotlin.Any
$receiver: CALL 'public final fun get (index: kotlin.Int): T of kotlin.Array [operator] declared in kotlin.Array' type=<root>.In<kotlin.Nothing> origin=GET_ARRAY_ELEMENT
$this: CALL 'public final fun select <S> (x: S of <root>.select, y: S of <root>.select): S of <root>.select declared in <root>' type=kotlin.Array<out <root>.In<kotlin.Nothing>> origin=null
<S>: kotlin.Array<out <root>.In<kotlin.Nothing>>
@@ -1437,6 +1437,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/function"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
@TestMetadata("argumentTypes.kt")
public void testArgumentTypes() throws Exception {
runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt");
}
@TestMetadata("booleanNotIntrinsic.kt")
public void testBooleanNotIntrinsic() throws Exception {
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");