FIR: fix substitution of type arguments in SAM type aliases
^KT-54730 Fixed
This commit is contained in:
+1
-1
@@ -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)
|
||||
}
|
||||
)
|
||||
|
||||
+6
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user