[IR] Erase non-trivial type projections off of super types
This fixes https://youtrack.jetbrains.com/issue/KT-44826
This commit is contained in:
committed by
Vasily Levchenko
parent
ca953d3186
commit
764f7f31d2
+19
-1
@@ -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"
|
||||
|
||||
+17
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user