IR: don't attempt to move defaults to actual in another module

May happen when a function in an `expect` class is aliased through an
`actual typealias`; the matching declaration is filtered out in
`ExpectedActualResolver.findActualForExpected` as it has no source.
This commit is contained in:
pyos
2019-11-15 14:14:01 +01:00
committed by Alexander Udalov
parent 1bc48c3df9
commit 9182f2c796
5 changed files with 38 additions and 12 deletions
@@ -63,7 +63,12 @@ class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, private va
return
}
val actualParameter = function.findActualForExpected().valueParameters[index]
// If the containing declaration is an `expect class` that matches an `actual typealias`,
// the `actual fun` or `actual constructor` for this may be in a different module.
// Nothing we can do with those.
// TODO they may not actually have the defaults though -- may be a frontend bug.
val actualFunction = function.findActualForExpected() ?: return
val actualParameter = actualFunction.valueParameters[index]
// Keep actual default value if present. They are generally not allowed but can be suppressed with
// @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
@@ -79,19 +84,19 @@ class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, private va
})
}
private fun IrFunction.findActualForExpected(): IrFunction =
symbolTable.referenceFunction(descriptor.findActualForExpect()).owner
private fun IrFunction.findActualForExpected(): IrFunction? =
descriptor.findActualForExpect()?.let { symbolTable.referenceFunction(it).owner }
private fun IrClass.findActualForExpected(): IrClass =
symbolTable.referenceClass(descriptor.findActualForExpect()).owner
private fun IrClass.findActualForExpected(): IrClass? =
descriptor.findActualForExpect()?.let { symbolTable.referenceClass(it).owner }
private inline fun <reified T : MemberDescriptor> T.findActualForExpect() = with(ExpectedActualResolver) {
val descriptor = this@findActualForExpect
if (!descriptor.isExpect) error(this)
findCompatibleActualForExpected(descriptor.module).singleOrNull() ?: error(descriptor)
} as T
findCompatibleActualForExpected(descriptor.module).singleOrNull()
} as T?
private fun IrExpression.remapExpectValueSymbols(): IrExpression {
return this.transform(object : IrElementTransformerVoid() {
@@ -123,17 +128,17 @@ class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, private va
return when (parent) {
is IrClass -> {
assert(parameter == parent.thisReceiver)
parent.findActualForExpected().thisReceiver!!
parent.findActualForExpected()!!.thisReceiver!!
}
is IrFunction -> when (parameter) {
parent.dispatchReceiverParameter ->
parent.findActualForExpected().dispatchReceiverParameter!!
parent.findActualForExpected()!!.dispatchReceiverParameter!!
parent.extensionReceiverParameter ->
parent.findActualForExpected().extensionReceiverParameter!!
parent.findActualForExpected()!!.extensionReceiverParameter!!
else -> {
assert(parent.valueParameters[parameter.index] == parameter)
parent.findActualForExpected().valueParameters[parameter.index]
parent.findActualForExpected()!!.valueParameters[parameter.index]
}
}
@@ -1,5 +1,4 @@
// !LANGUAGE: +MultiPlatformProjects
// IGNORE_BACKEND: JVM_IR
// WITH_REFLECT
// FILE: main.kt
@@ -0,0 +1,12 @@
// !LANGUAGE: +MultiPlatformProjects
// FILE: impl.kt
class A(val result: String = "OK")
// FILE: multiplatform.kt
expect class B(result: String = "FAIL")
actual typealias B = A
fun box(): String {
return B().result
}
@@ -128,6 +128,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
runTest("compiler/testData/compileKotlinAgainstKotlin/enum.kt");
}
@TestMetadata("expectClassActualTypeAlias.kt")
public void testExpectClassActualTypeAlias() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/expectClassActualTypeAlias.kt");
}
@TestMetadata("inlineClassFromBinaryDependencies.kt")
public void testInlineClassFromBinaryDependencies() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");
@@ -123,6 +123,11 @@ public class IrCompileKotlinAgainstKotlinTestGenerated extends AbstractIrCompile
runTest("compiler/testData/compileKotlinAgainstKotlin/enum.kt");
}
@TestMetadata("expectClassActualTypeAlias.kt")
public void testExpectClassActualTypeAlias() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/expectClassActualTypeAlias.kt");
}
@TestMetadata("inlineClassFromBinaryDependencies.kt")
public void testInlineClassFromBinaryDependencies() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");