[K/N][IR] Fix for https://youtrack.jetbrains.com/issue/KT-47814
This commit is contained in:
+23
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMo
|
||||
import org.jetbrains.kotlin.backend.konan.MemoryModel
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.lower.ExpectToActualDefaultValueCopier
|
||||
import org.jetbrains.kotlin.backend.konan.lower.SamSuperTypesChecker
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanIdSignaturer
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleSerializer
|
||||
@@ -149,6 +150,26 @@ internal val copyDefaultValuesToActualPhase = konanUnitPhase(
|
||||
description = "Copy default values from expect to actual declarations"
|
||||
)
|
||||
|
||||
/*
|
||||
* Sometimes psi2ir produces IR with non-trivial variance in super types of SAM conversions (this is a language design issue).
|
||||
* Earlier this was solved with just erasing all such variances but this might lead to some other hard to debug problems,
|
||||
* so after handling the majority of corner cases correctly in psi2ir it is safe to assume that such cases don't get here and
|
||||
* even if they do, then it's better to throw an error right away than to dig out weird crashes down the pipeline or even at runtime.
|
||||
* We explicitly check this, also fixing older klibs built with previous compiler versions by applying the same trick as before.
|
||||
*/
|
||||
internal val checkSamSuperTypesPhase = konanUnitPhase(
|
||||
op = {
|
||||
irModule!!.files
|
||||
.forEach { SamSuperTypesChecker(this, it, mode = SamSuperTypesChecker.Mode.THROW).run() }
|
||||
// TODO: This is temporary for handling klibs produced with earlier compiler versions.
|
||||
irModules.values
|
||||
.flatMap { it.files }
|
||||
.forEach { SamSuperTypesChecker(this, it, mode = SamSuperTypesChecker.Mode.ERASE).run() }
|
||||
},
|
||||
name = "CheckSamSuperTypes",
|
||||
description = "Check SAM conversions super types"
|
||||
)
|
||||
|
||||
internal val serializerPhase = konanUnitPhase(
|
||||
op = {
|
||||
val expectActualLinker = config.configuration.get(CommonConfigurationKeys.EXPECT_ACTUAL_LINKER) ?: false
|
||||
@@ -424,6 +445,7 @@ val toplevelPhase: CompilerPhase<*, Unit, Unit> = namedUnitPhase(
|
||||
psiToIrPhase then
|
||||
destroySymbolTablePhase then
|
||||
copyDefaultValuesToActualPhase then
|
||||
checkSamSuperTypesPhase then
|
||||
serializerPhase then
|
||||
specialBackendChecksPhase then
|
||||
namedUnitPhase(
|
||||
@@ -484,5 +506,6 @@ internal fun PhaseConfig.konanPhasesConfig(config: KonanConfig) {
|
||||
disableIf(destroySymbolTablePhase, isDescriptorsOnlyLibrary)
|
||||
disableIf(copyDefaultValuesToActualPhase, isDescriptorsOnlyLibrary)
|
||||
disableIf(specialBackendChecksPhase, isDescriptorsOnlyLibrary)
|
||||
disableIf(checkSamSuperTypesPhase, isDescriptorsOnlyLibrary)
|
||||
}
|
||||
}
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.backend.konan.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.reportCompilationError
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeProjection
|
||||
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
internal class SamSuperTypesChecker(private val context: Context,
|
||||
private val irFile: IrFile,
|
||||
private val mode: Mode) {
|
||||
enum class Mode {
|
||||
ERASE,
|
||||
THROW
|
||||
}
|
||||
|
||||
private fun IrType.eraseProjections(owner: IrElement): IrType {
|
||||
if (this !is IrSimpleType) return this
|
||||
return buildSimpleType {
|
||||
this.classifier = this@eraseProjections.classifier
|
||||
this.hasQuestionMark = this@eraseProjections.hasQuestionMark
|
||||
this.annotations = this@eraseProjections.annotations
|
||||
this.arguments = this@eraseProjections.arguments.mapIndexed { index, argument ->
|
||||
if (argument !is IrTypeProjection)
|
||||
argument
|
||||
else {
|
||||
if (mode == Mode.THROW && argument.variance != Variance.INVARIANT) {
|
||||
context.reportCompilationError(
|
||||
"Unexpected variance in super type argument: ${argument.variance} @$index", irFile, owner)
|
||||
}
|
||||
makeTypeProjection(argument.type.eraseProjections(owner), Variance.INVARIANT)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun run() {
|
||||
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
if (expression.operator == IrTypeOperator.SAM_CONVERSION)
|
||||
expression.typeOperand = expression.typeOperand.eraseProjections(expression)
|
||||
return expression
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user