An option to allow out-of-scope type parameters in IrManglerComputer
In the lowered IR there are often references to type parameters whose containers are not in the current scope. This is incorrect semantically, but it works in practice due to erasure, so when the mangler is used on the lowered IR, we don't want to crash the compiler.
This commit is contained in:
committed by
Space Team
parent
e3a4d6fa56
commit
f40278c036
+5
-2
@@ -19,10 +19,13 @@ import org.jetbrains.kotlin.types.model.*
|
|||||||
* @param Session An additional context used for type computations.
|
* @param Session An additional context used for type computations.
|
||||||
* @property builder A string builder to write the mangled name into.
|
* @property builder A string builder to write the mangled name into.
|
||||||
* @property mode The mangle mode.
|
* @property mode The mangle mode.
|
||||||
|
* @property allowOutOfScopeTypeParameters Whether to throw an exception if the container of a referenced type parameter is not found
|
||||||
|
* in the current scope. This often happens in the lowered IR and should never happen in the IR emitted by the frontend.
|
||||||
*/
|
*/
|
||||||
abstract class BaseKotlinMangleComputer<Declaration, Type, TypeParameter, ValueParameter, TypeParameterContainer, FunctionDeclaration, Session>(
|
abstract class BaseKotlinMangleComputer<Declaration, Type, TypeParameter, ValueParameter, TypeParameterContainer, FunctionDeclaration, Session>(
|
||||||
protected val builder: StringBuilder,
|
protected val builder: StringBuilder,
|
||||||
protected val mode: MangleMode
|
protected val mode: MangleMode,
|
||||||
|
protected val allowOutOfScopeTypeParameters: Boolean = false,
|
||||||
) : KotlinMangleComputer<Declaration>
|
) : KotlinMangleComputer<Declaration>
|
||||||
where Declaration : Any,
|
where Declaration : Any,
|
||||||
Type : KotlinTypeMarker,
|
Type : KotlinTypeMarker,
|
||||||
@@ -120,7 +123,7 @@ abstract class BaseKotlinMangleComputer<Declaration, Type, TypeParameter, ValueP
|
|||||||
protected fun StringBuilder.mangleTypeParameterReference(typeParameter: TypeParameter) {
|
protected fun StringBuilder.mangleTypeParameterReference(typeParameter: TypeParameter) {
|
||||||
val parent = getEffectiveParent(typeParameter)
|
val parent = getEffectiveParent(typeParameter)
|
||||||
val containerIndex = typeParameterContainers.indexOf(parent)
|
val containerIndex = typeParameterContainers.indexOf(parent)
|
||||||
require(containerIndex >= 0) {
|
require(allowOutOfScopeTypeParameters || containerIndex >= 0) {
|
||||||
"No container found for type parameter '${getTypeParameterName(typeParameter)}' of '${renderDeclaration(parent)}'"
|
"No container found for type parameter '${getTypeParameterName(typeParameter)}' of '${renderDeclaration(parent)}'"
|
||||||
}
|
}
|
||||||
appendSignature(containerIndex)
|
appendSignature(containerIndex)
|
||||||
|
|||||||
+3
-2
@@ -22,7 +22,8 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
|||||||
open class IrMangleComputer(
|
open class IrMangleComputer(
|
||||||
builder: StringBuilder,
|
builder: StringBuilder,
|
||||||
mode: MangleMode,
|
mode: MangleMode,
|
||||||
protected val compatibleMode: Boolean
|
protected val compatibleMode: Boolean,
|
||||||
|
allowOutOfScopeTypeParameters: Boolean = false,
|
||||||
) : BaseKotlinMangleComputer<
|
) : BaseKotlinMangleComputer<
|
||||||
/*Declaration=*/IrDeclaration,
|
/*Declaration=*/IrDeclaration,
|
||||||
/*Type=*/IrType,
|
/*Type=*/IrType,
|
||||||
@@ -31,7 +32,7 @@ open class IrMangleComputer(
|
|||||||
/*TypeParameterContainer=*/IrDeclaration,
|
/*TypeParameterContainer=*/IrDeclaration,
|
||||||
/*FunctionDeclaration=*/IrFunction,
|
/*FunctionDeclaration=*/IrFunction,
|
||||||
/*Session=*/Nothing?,
|
/*Session=*/Nothing?,
|
||||||
>(builder, mode) {
|
>(builder, mode, allowOutOfScopeTypeParameters) {
|
||||||
|
|
||||||
final override fun getTypeSystemContext(session: Nothing?) = object : IrTypeSystemContext {
|
final override fun getTypeSystemContext(session: Nothing?) = object : IrTypeSystemContext {
|
||||||
override val irBuiltIns: IrBuiltIns
|
override val irBuiltIns: IrBuiltIns
|
||||||
|
|||||||
@@ -14,7 +14,32 @@ class N(val v: Int) : IntConvertible {
|
|||||||
override fun toInt() = v
|
override fun toInt() = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Grouping<GroupingInputTP, out GroupingOutputTP> {
|
||||||
|
fun keyOf(element: GroupingInputTP): GroupingOutputTP
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <GroupingByTP> groupingBy(keySelector: (Char) -> GroupingByTP): Grouping<Char, GroupingByTP> {
|
||||||
|
|
||||||
|
fun <T> foo(p0: T, p1: GroupingByTP) {}
|
||||||
|
|
||||||
|
foo(0, keySelector('a'))
|
||||||
|
|
||||||
|
class A<T>(p0: T, p1: GroupingByTP) {}
|
||||||
|
|
||||||
|
A(0, keySelector('a'))
|
||||||
|
|
||||||
|
return object : Grouping<Char, GroupingByTP> {
|
||||||
|
override fun keyOf(element: Char): GroupingByTP = keySelector(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Delft<DelftTP> {
|
||||||
|
fun getComparator(other: DelftTP) = { this == other }
|
||||||
|
}
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
if (computeSum(arrayOf(N(2), N(14))) != 16) return "Fail"
|
if (computeSum(arrayOf(N(2), N(14))) != 16) return "Fail1"
|
||||||
|
|
||||||
|
if (groupingBy { it }.keyOf('A') != 'A') return "Fail2"
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
// TODO: do not serialize descriptors of non-exported declarations.
|
// TODO: do not serialize descriptors of non-exported declarations.
|
||||||
|
|
||||||
object KonanBinaryInterface {
|
object KonanBinaryInterface {
|
||||||
private val mangler = object : AbstractKonanIrMangler(true) {}
|
private val mangler = object : AbstractKonanIrMangler(withReturnType = true, allowOutOfScopeTypeParameters = true) {}
|
||||||
|
|
||||||
private val exportChecker = mangler.getExportChecker(compatibleMode = true)
|
private val exportChecker = mangler.getExportChecker(compatibleMode = true)
|
||||||
|
|
||||||
|
|||||||
+16
-5
@@ -15,10 +15,14 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.types.getClass
|
import org.jetbrains.kotlin.ir.types.getClass
|
||||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||||
|
|
||||||
abstract class AbstractKonanIrMangler(private val withReturnType: Boolean) : IrBasedKotlinManglerImpl() {
|
abstract class AbstractKonanIrMangler(
|
||||||
|
private val withReturnType: Boolean,
|
||||||
|
private val allowOutOfScopeTypeParameters: Boolean = false
|
||||||
|
) : IrBasedKotlinManglerImpl() {
|
||||||
override fun getExportChecker(compatibleMode: Boolean): IrExportCheckerVisitor = KonanIrExportChecker(compatibleMode)
|
override fun getExportChecker(compatibleMode: Boolean): IrExportCheckerVisitor = KonanIrExportChecker(compatibleMode)
|
||||||
|
|
||||||
override fun getMangleComputer(mode: MangleMode, compatibleMode: Boolean): IrMangleComputer = KonanIrManglerComputer(StringBuilder(256), mode, compatibleMode, withReturnType)
|
override fun getMangleComputer(mode: MangleMode, compatibleMode: Boolean): IrMangleComputer =
|
||||||
|
KonanIrManglerComputer(StringBuilder(256), mode, compatibleMode, withReturnType, allowOutOfScopeTypeParameters)
|
||||||
|
|
||||||
override fun IrDeclaration.isPlatformSpecificExport(): Boolean {
|
override fun IrDeclaration.isPlatformSpecificExport(): Boolean {
|
||||||
if (this is IrSimpleFunction) if (isFakeOverride) return false
|
if (this is IrSimpleFunction) if (isFakeOverride) return false
|
||||||
@@ -51,8 +55,15 @@ abstract class AbstractKonanIrMangler(private val withReturnType: Boolean) : IrB
|
|||||||
override fun IrDeclaration.isPlatformSpecificExported(): Boolean = isPlatformSpecificExport()
|
override fun IrDeclaration.isPlatformSpecificExported(): Boolean = isPlatformSpecificExport()
|
||||||
}
|
}
|
||||||
|
|
||||||
private class KonanIrManglerComputer(builder: StringBuilder, mode: MangleMode, compatibleMode: Boolean, private val withReturnType: Boolean) : IrMangleComputer(builder, mode, compatibleMode) {
|
private class KonanIrManglerComputer(
|
||||||
override fun copy(newMode: MangleMode): IrMangleComputer = KonanIrManglerComputer(builder, newMode, compatibleMode, withReturnType)
|
builder: StringBuilder,
|
||||||
|
mode: MangleMode,
|
||||||
|
compatibleMode: Boolean,
|
||||||
|
private val withReturnType: Boolean,
|
||||||
|
allowOutOfScopeTypeParameters: Boolean,
|
||||||
|
) : IrMangleComputer(builder, mode, compatibleMode, allowOutOfScopeTypeParameters) {
|
||||||
|
override fun copy(newMode: MangleMode): IrMangleComputer =
|
||||||
|
KonanIrManglerComputer(builder, newMode, compatibleMode, withReturnType, allowOutOfScopeTypeParameters)
|
||||||
|
|
||||||
override fun addReturnType(): Boolean = withReturnType
|
override fun addReturnType(): Boolean = withReturnType
|
||||||
|
|
||||||
@@ -166,4 +177,4 @@ abstract class AbstractKonanDescriptorMangler : DescriptorBasedKotlinManglerImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object KonanManglerDesc : AbstractKonanDescriptorMangler()
|
object KonanManglerDesc : AbstractKonanDescriptorMangler()
|
||||||
|
|||||||
Reference in New Issue
Block a user