[IR] Erase non-trivial type projections off of super types

This fixes https://youtrack.jetbrains.com/issue/KT-44826
This commit is contained in:
Igor Chevdar
2021-02-17 14:06:11 +05:00
committed by Vasily Levchenko
parent ca953d3186
commit 764f7f31d2
3 changed files with 40 additions and 1 deletions
@@ -32,10 +32,13 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance
internal class FunctionReferenceLowering(val context: Context): FileLoweringPass {
@@ -89,6 +92,21 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
return result
}
// TODO: Move to common IR utils.
fun IrType.eraseProjections(): 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.map {
if (it !is IrTypeProjection)
it
else makeTypeProjection(it.type.eraseProjections(), Variance.INVARIANT)
}
}
}
// Handle SAM conversions which wrap a function reference:
// class sam$n(private val receiver: R) : Interface { override fun method(...) = receiver.target(...) }
//
@@ -111,7 +129,7 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
return super.visitTypeOperator(expression)
}
reference.transformChildrenVoid()
return transformFunctionReference(reference, expression.typeOperand)
return transformFunctionReference(reference, expression.typeOperand.eraseProjections())
}
return super.visitTypeOperator(expression)
}
@@ -2881,6 +2881,10 @@ task funInterface_implIsNotFunction(type: KonanLocalTest) {
source = "codegen/funInterface/implIsNotFunction.kt"
}
task funInterface_nonTrivialProjectionInSuperType(type: KonanLocalTest) {
source = "codegen/funInterface/nonTrivialProjectionInSuperType.kt"
}
task objectExpression1(type: KonanLocalTest) {
goldValue = "aabb\n"
source = "codegen/objectExpression/expr1.kt"
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
package codegen.funInterface.nonTrivialProjectionInSuperType
import kotlin.test.*
fun <T> foo(comparator: kotlin.Comparator<in T>, a: T, b: T) = comparator.compare(a, b)
fun bar(x: Int, y: Int) = foo<Int> ({ a, b -> a - b}, x, y)
@Test
fun test() {
assertTrue(bar(42, 117) < 0)
}