K2: Do not use KFunctionN as representation type for adapted references

Beside some corner cases, it's already prohibited in K1 because
adaptation have a bit strange nature
(they don't represent any existing real function exactly)

^KT-55137 Fixed
This commit is contained in:
Denis.Zharkov
2022-11-25 18:19:10 +01:00
committed by Space Team
parent dcdc48a233
commit a38040680c
17 changed files with 102 additions and 18 deletions
@@ -3117,6 +3117,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/adapted"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("noKFunctionForAdaptation.kt")
public void testNoKFunctionForAdaptation() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/adapted/noKFunctionForAdaptation.kt");
}
@Test
@TestMetadata("simpleAdaptationOutsideOfCall.kt")
public void testSimpleAdaptationOutsideOfCall() throws Exception {
@@ -3111,6 +3111,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/adapted"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("noKFunctionForAdaptation.kt")
public void testNoKFunctionForAdaptation() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/adapted/noKFunctionForAdaptation.kt");
}
@Test
@TestMetadata("simpleAdaptationOutsideOfCall.kt")
public void testSimpleAdaptationOutsideOfCall() throws Exception {
@@ -98,8 +98,7 @@ internal class AdapterGenerator(
* At the use site, instead of referenced, we can put the suspend lambda as an adapter.
*/
private fun needSuspendConversion(type: IrSimpleType, function: IrFunction): Boolean =
// TODO: should refer to LanguageVersionSettings.SuspendConversion
type.isKSuspendFunction() && !function.isSuspend
type.isSuspendFunction() && !function.isSuspend
/**
* For example,
@@ -133,9 +132,6 @@ internal class AdapterGenerator(
}
}
internal fun ConeKotlinType.kFunctionTypeToFunctionType(): IrSimpleType =
reflectFunctionTypeToNonReflectFunctionType(session).toIrType() as IrSimpleType
internal fun generateAdaptedCallableReference(
callableReferenceAccess: FirCallableReferenceAccess,
explicitReceiverExpression: IrExpression?,
@@ -156,7 +156,8 @@ class CallAndReferenceGenerator(
if (adapterGenerator.needToGenerateAdaptedCallableReference(callableReferenceAccess, type, function)) {
// Receivers are being applied inside
with(adapterGenerator) {
val adaptedType = callableReferenceAccess.typeRef.coneType.kFunctionTypeToFunctionType()
// TODO: Figure out why `adaptedType` is different from the `type`?
val adaptedType = callableReferenceAccess.typeRef.coneType.toIrType() as IrSimpleType
generateAdaptedCallableReference(callableReferenceAccess, explicitReceiverExpression, symbol, adaptedType)
}
} else {
@@ -18319,6 +18319,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/fir/assertEqualsFakeOverride.kt");
}
@Test
@TestMetadata("callableReferenceConversionTopLevel.kt")
public void testCallableReferenceConversionTopLevel() throws Exception {
runTest("compiler/testData/codegen/box/fir/callableReferenceConversionTopLevel.kt");
}
@Test
@TestMetadata("callableReferenceToJavaField.kt")
public void testCallableReferenceToJavaField() throws Exception {
@@ -136,7 +136,7 @@ private fun buildReflectionType(
?: FunctionTypeKind.Function
return createFunctionType(
baseFunctionTypeKind.reflectKind(),
if (callableReferenceAdaptation == null) baseFunctionTypeKind.reflectKind() else baseFunctionTypeKind.nonReflectKind(),
parameters,
receiverType = receiverType.takeIf { fir.receiverParameter != null },
rawReturnType = returnType,
@@ -239,9 +239,11 @@ private fun BodyResolveComponents.getCallableReferenceAdaptation(
mappedArguments[valueParameter] = ResolvedCallArgument.VarargArgument(varargElements)
}
var isThereVararg = mappedVarargElements.isNotEmpty()
for (valueParameter in function.valueParameters) {
if (valueParameter.isVararg && valueParameter !in mappedArguments) {
mappedArguments[valueParameter] = ResolvedCallArgument.VarargArgument(emptyList())
isThereVararg = true
}
}
@@ -264,6 +266,14 @@ private fun BodyResolveComponents.getCallableReferenceAdaptation(
CallableReferenceConversionStrategy.NoConversion
}
if (defaults == 0 && !isThereVararg &&
coercionStrategy == CoercionStrategy.NO_COERCION && conversionStrategy == CallableReferenceConversionStrategy.NoConversion
) {
// Do not create adaptation for trivial (id) conversion as it makes resulting type FunctionN instead of KFunctionN
// It happens because adapted references do not support reflection (see KT-40406)
return null
}
@Suppress("UNCHECKED_CAST")
return CallableReferenceAdaptation(
mappedArgumentTypes as Array<ConeKotlinType>,