Psi2Ir: Fix SAM conversion with new inference

This commit is contained in:
Steven Schäfer
2020-08-21 11:21:51 +02:00
committed by Dmitry Petrov
parent 75891e860b
commit 44ffb1fb3e
8 changed files with 49 additions and 16 deletions
@@ -15065,6 +15065,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/javaInterop/genericSamProjectedOutWithNewInference.kt");
}
@TestMetadata("genericSamSmartcast.kt")
public void testGenericSamSmartcast() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/genericSamSmartcast.kt");
}
@TestMetadata("lambdaInstanceOf.kt")
public void testLambdaInstanceOf() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/lambdaInstanceOf.kt");
@@ -613,12 +613,13 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca
for (i in underlyingValueParameters.indices) {
val underlyingValueParameter = underlyingValueParameters[i]
val expectedSamConversionTypesForVararg = ArrayList<KotlinType?>()
if (expectSamConvertedArgumentToBeAvailableInResolvedCall && resolvedCall is NewResolvedCallImpl<*>) {
val arguments = resolvedCall.valueArguments[originalValueParameters[i]]?.arguments ?: continue
arguments.mapTo(expectedSamConversionTypesForVararg) { resolvedCall.getExpectedTypeForSamConvertedArgument(it) }
if (expectedSamConversionTypesForVararg.all { it == null }) continue
} else {
val expectedSamConversionTypesForVararg =
if (expectSamConvertedArgumentToBeAvailableInResolvedCall && resolvedCall is NewResolvedCallImpl<*>) {
val arguments = resolvedCall.valueArguments[originalValueParameters[i]]?.arguments
arguments?.map { resolvedCall.getExpectedTypeForSamConvertedArgument(it) }
} else null
if (expectedSamConversionTypesForVararg?.all { it == null } != false) {
// 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.
@@ -675,8 +676,7 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca
).apply {
originalArgument.elements.mapIndexedTo(elements) { index, element ->
if (element is IrExpression) {
val samType = expectedSamConversionTypesForVararg[index]
if (samType != null)
if (expectedSamConversionTypesForVararg?.get(index) != null)
samConvertScalarExpression(element)
else
element
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
@@ -32,11 +31,6 @@ class ExternalDependenciesGenerator(
private val languageVersionSettings: LanguageVersionSettings
) {
fun generateUnboundSymbolsAsDependencies() {
if (languageVersionSettings.supportsFeature(LanguageFeature.NewInference)) {
require(symbolTable.unboundTypeParameters.isEmpty()) {
"Unbound type parameters are forbidden: ${symbolTable.unboundTypeParameters}"
}
}
// There should be at most one DeclarationStubGenerator (none in closed world?)
irProviders.singleOrNull { it is DeclarationStubGenerator }?.let {
(it as DeclarationStubGenerator).unboundSymbolGeneration = true
@@ -1,6 +1,4 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
// FILE: example/Hello.java
package example;
@@ -0,0 +1,21 @@
// TARGET_BACKEND: JVM
// FILE: A.java
public class A<T> {
public interface I<T> {
String apply(T x);
}
public String call(I<T> block) { return block.apply(null); }
}
// FILE: test.kt
fun f(x: Any): String {
if (x is A<*>) {
return x.call { y: Any? -> "OK" }
}
return "Fail"
}
fun box(): String {
return f(A<Int>())
}
@@ -16290,6 +16290,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/javaInterop/genericSamProjectedOutWithNewInference.kt");
}
@TestMetadata("genericSamSmartcast.kt")
public void testGenericSamSmartcast() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/genericSamSmartcast.kt");
}
@TestMetadata("lambdaInstanceOf.kt")
public void testLambdaInstanceOf() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/lambdaInstanceOf.kt");
@@ -16290,6 +16290,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/javaInterop/genericSamProjectedOutWithNewInference.kt");
}
@TestMetadata("genericSamSmartcast.kt")
public void testGenericSamSmartcast() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/genericSamSmartcast.kt");
}
@TestMetadata("lambdaInstanceOf.kt")
public void testLambdaInstanceOf() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/lambdaInstanceOf.kt");
@@ -15065,6 +15065,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/javaInterop/genericSamProjectedOutWithNewInference.kt");
}
@TestMetadata("genericSamSmartcast.kt")
public void testGenericSamSmartcast() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/genericSamSmartcast.kt");
}
@TestMetadata("lambdaInstanceOf.kt")
public void testLambdaInstanceOf() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/lambdaInstanceOf.kt");