FIR: fix substitution of type arguments in SAM type aliases

^KT-54730 Fixed
This commit is contained in:
pyos
2022-10-20 13:22:50 +02:00
committed by Space Team
parent 3253789093
commit 0d46dfc1ba
20 changed files with 125 additions and 72 deletions
@@ -1,6 +1,6 @@
FILE: kotlinComparatorAlias.kt
public final fun test_1(): R|kotlin/Unit| {
lval comp: R|java/util/Comparator<kotlin/Int>| = R|java/util/Comparator|<R|kotlin/Int|>(<L> = Comparator@fun <anonymous>(x: R|kotlin/Int!|, y: R|kotlin/Int!|): R|kotlin/Int| <inline=NoInline> {
lval comp: R|java/util/Comparator<kotlin/Int>| = R|kotlin/Comparator|<R|kotlin/Int|>(<L> = Comparator@fun <anonymous>(x: R|kotlin/Int!|, y: R|kotlin/Int!|): R|kotlin/Int| <inline=NoInline> {
^ Int(1)
}
)
@@ -18461,6 +18461,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/funInterface/funInterfaceInheritance.kt");
}
@Test
@TestMetadata("funInterfaceTypealias.kt")
public void testFunInterfaceTypealias() throws Exception {
runTest("compiler/testData/codegen/box/funInterface/funInterfaceTypealias.kt");
}
@Test
@TestMetadata("funInterfaceWithReceiver.kt")
public void testFunInterfaceWithReceiver() throws Exception {
@@ -111,14 +111,7 @@ class FirSamResolverImpl(
val firRegularClass = classSymbol.fir
val (functionSymbol, functionType) = resolveFunctionTypeIfSamInterface(firRegularClass) ?: return null
val classId = firRegularClass.classId
val syntheticFunctionSymbol = FirSyntheticFunctionSymbol(
CallableId(
classId.packageFqName,
classId.relativeClassName.parent().takeIf { !it.isRoot },
classId.shortClassName,
),
)
val syntheticFunctionSymbol = classSymbol.createSyntheticConstructorSymbol()
val newTypeParameters = firRegularClass.typeParameters.map { typeParameter ->
val declaredTypeParameter = typeParameter.symbol.fir // TODO: or really declared?
@@ -160,7 +153,7 @@ class FirSamResolverImpl(
return buildSimpleFunction {
moduleData = session.moduleData
source = firRegularClass.source
name = classId.shortClassName
name = syntheticFunctionSymbol.name
origin = FirDeclarationOrigin.SamConstructor
val visibility = firRegularClass.visibility
status = FirResolvedDeclarationStatusImpl(
@@ -223,7 +216,10 @@ class FirSamResolverImpl(
val expansionRegularClass = type.lookupTag.toSymbol(session)?.fir as? FirRegularClass ?: return null
val samConstructorForClass = getSamConstructor(expansionRegularClass) ?: return null
val substitutor = expansionRegularClass.buildSubstitutorForSamTypeAlias(session, type)
// The constructor is something like `fun <T, ...> C(...): C<T, ...>`, meaning the type parameters
// we need to replace are owned by it, not by the class (see the substitutor in `buildSamConstructor`
// for `FirRegularClass` above).
val substitutor = samConstructorForClass.buildSubstitutorForSamTypeAlias(session, type)
?: return samConstructorForClass.symbol
val newReturnType = substitutor.substituteOrNull(samConstructorForClass.returnTypeRef.coneType)
val newParameterTypes = samConstructorForClass.valueParameters.map {
@@ -236,19 +232,28 @@ class FirSamResolverImpl(
return samConstructorForClass.symbol
}
val namedSymbol = samConstructorForClass.symbol
val symbolForOverride = FirFakeOverrideGenerator.createSymbolForSubstitutionOverride(namedSymbol, expansionRegularClass.classId)
return FirFakeOverrideGenerator.createSubstitutionOverrideFunction(
session, symbolForOverride, samConstructorForClass,
return FirFakeOverrideGenerator.createCopyForFirFunction(
typeAliasSymbol.createSyntheticConstructorSymbol(), samConstructorForClass,
derivedClassLookupTag = null,
session, FirDeclarationOrigin.SamConstructor,
newDispatchReceiverType = null,
newReceiverType = null,
newContextReceiverTypes,
newReturnType, newParameterTypes, typeAliasSymbol.fir.typeParameters,
)
newContextReceiverTypes = newContextReceiverTypes,
newReturnType = newReturnType,
newParameterTypes = newParameterTypes,
newTypeParameters = typeAliasSymbol.fir.typeParameters,
).symbol
}
private fun FirClassLikeSymbol<*>.createSyntheticConstructorSymbol() =
FirSyntheticFunctionSymbol(
CallableId(
classId.packageFqName,
classId.relativeClassName.parent().takeIf { !it.isRoot },
classId.shortClassName,
),
)
private fun resolveFunctionTypeIfSamInterface(firRegularClass: FirRegularClass): SAMInfo<ConeLookupTagBasedType>? {
return resolvedFunctionType.getOrPut(firRegularClass) {
if (!firRegularClass.status.isFun) return@getOrPut null
@@ -269,7 +274,7 @@ class FirSamResolverImpl(
}
}
private fun FirRegularClass.buildSubstitutorForSamTypeAlias(session: FirSession, type: ConeClassLikeType): ConeSubstitutor? {
private fun FirTypeParameterRefsOwner.buildSubstitutorForSamTypeAlias(session: FirSession, type: ConeClassLikeType): ConeSubstitutor? {
if (typeParameters.isEmpty()) return null
val mapping = typeParameters.zip(type.typeArguments).associate { (parameter, projection) ->
val typeArgument =