PSI2IR: support SAM conversion to substituted types
i.e. in arguments to `f(T x)` where `T` is a type parameter bound to a SAM type.
This commit is contained in:
Generated
+5
@@ -14588,6 +14588,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/javaInterop/protectedField.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samTypeParameter.kt")
|
||||
public void testSamTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/samTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samUnboundTypeParameter.kt")
|
||||
public void testSamUnboundTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/samUnboundTypeParameter.kt");
|
||||
|
||||
+7
-3
@@ -620,14 +620,18 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca
|
||||
|
||||
for (i in underlyingValueParameters.indices) {
|
||||
val underlyingValueParameter = underlyingValueParameters[i]
|
||||
val originalUnderlyingParameterType = underlyingValueParameter.original.type
|
||||
|
||||
if (expectSamConvertedArgumentToBeAvailableInResolvedCall && resolvedCall is NewResolvedCallImpl<*>) {
|
||||
// TODO support SAM conversion of varargs
|
||||
val argument = resolvedCall.valueArguments[originalValueParameters[i]]?.arguments?.singleOrNull() ?: continue
|
||||
resolvedCall.getExpectedTypeForSamConvertedArgument(argument) ?: continue
|
||||
} else {
|
||||
if (!context.extensions.samConversion.isSamType(originalUnderlyingParameterType)) continue
|
||||
// When the method is `f(T)` with `T` = a SAM type, the substituted type is a SAM while the original is not;
|
||||
// when the method is `f(X<T>)` with `T` = `out V` where `X` is a SAM type, the substituted type is `Nothing`
|
||||
// while the original is a SAM interface. Thus, if *either* of those is a SAM type then it's fine.
|
||||
if (!samConversion.isSamType(underlyingValueParameter.type) &&
|
||||
!samConversion.isSamType(underlyingValueParameter.original.type)
|
||||
) continue
|
||||
if (!originalValueParameters[i].type.isFunctionTypeOrSubtype) continue
|
||||
}
|
||||
|
||||
@@ -640,7 +644,7 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca
|
||||
val substitutedSamType = typeSubstitutor.substitute(samKotlinType, Variance.INVARIANT)
|
||||
?: throw AssertionError(
|
||||
"Failed to substitute value argument type in SAM conversion: " +
|
||||
"underlyingParameterType=$originalUnderlyingParameterType, " +
|
||||
"underlyingParameterType=${underlyingValueParameter.type}, " +
|
||||
"substitutionContext=$substitutionContext"
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// TODO: new inference doesn't do SAM conversion in this case. KT-37149
|
||||
// !LANGUAGE: -NewInference
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// FILE: Generic.java
|
||||
class Generic<T> {
|
||||
T id(T x) { return x; }
|
||||
}
|
||||
|
||||
// FILE: Specialized.java
|
||||
class Specialized extends Generic<Runnable> {}
|
||||
|
||||
// FILE: use.kt
|
||||
fun box(): String {
|
||||
var result = "fail"
|
||||
Specialized().id { result = "OK" }.run()
|
||||
return result
|
||||
}
|
||||
+5
@@ -15803,6 +15803,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/protectedField.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samTypeParameter.kt")
|
||||
public void testSamTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/samTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samUnboundTypeParameter.kt")
|
||||
public void testSamUnboundTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/samUnboundTypeParameter.kt");
|
||||
|
||||
+5
@@ -15803,6 +15803,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/javaInterop/protectedField.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samTypeParameter.kt")
|
||||
public void testSamTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/samTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samUnboundTypeParameter.kt")
|
||||
public void testSamUnboundTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/samUnboundTypeParameter.kt");
|
||||
|
||||
+5
@@ -14588,6 +14588,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/javaInterop/protectedField.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samTypeParameter.kt")
|
||||
public void testSamTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/samTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samUnboundTypeParameter.kt")
|
||||
public void testSamUnboundTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/samUnboundTypeParameter.kt");
|
||||
|
||||
Reference in New Issue
Block a user