Fix SAM conversion when lambda is the last expression of another lambda

#KT-39691 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2020-07-20 10:36:37 +03:00
parent a15d3c76b6
commit 4083111dab
6 changed files with 79 additions and 0 deletions
@@ -19776,6 +19776,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/samConversions/checkSamConversionsAreDisabledByDefault.kt");
}
@TestMetadata("conversionOnLambdaAsLastExpression.kt")
public void testConversionOnLambdaAsLastExpression() throws Exception {
runTest("compiler/testData/diagnostics/tests/samConversions/conversionOnLambdaAsLastExpression.kt");
}
@TestMetadata("DisabledForKTSimple.kt")
public void testDisabledForKTSimple() throws Exception {
runTest("compiler/testData/diagnostics/tests/samConversions/DisabledForKTSimple.kt");
@@ -45,12 +45,29 @@ object SamTypeConversions : ParameterTypeConversion {
override fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean {
return when (argument) {
is SubKotlinCallArgument -> {
val stableType = argument.receiver.stableType
hasNonAnalyzedLambdaAsReturnType(argument.callResult.subResolvedAtoms, stableType)
}
is SimpleKotlinCallArgument -> argument.receiver.stableType.isFunctionType
is LambdaKotlinCallArgument, is CallableReferenceKotlinCallArgument -> true
else -> false
}
}
private fun hasNonAnalyzedLambdaAsReturnType(subResolvedAtoms: List<ResolvedAtom>?, type: UnwrappedType): Boolean {
subResolvedAtoms?.forEach {
if (it is LambdaWithTypeVariableAsExpectedTypeAtom) {
if (it.expectedType.constructor == type.constructor) return true
}
val hasNonAnalyzedLambda = hasNonAnalyzedLambdaAsReturnType(it.subResolvedAtoms, type)
if (hasNonAnalyzedLambda) return true
}
return false
}
override fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean {
return argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionTypeOrSubtype
}
@@ -0,0 +1,20 @@
// FIR_IDENTICAL
// FILE: C.java
public interface C { void on(String s); }
// FILE: A.java
public class A { void add(C c) {} }
// FILE: test.kt
class B : A() {
fun test(x: Any?) {
add(foo { { _ : String -> Unit } })
add(x?.let { { _ : String -> Unit } })
}
}
fun <T> foo(f: () -> T): T = f()
@@ -0,0 +1,27 @@
package
public fun </*0*/ T> foo(/*0*/ f: () -> T): T
public open class A {
public constructor A()
public/*package*/ open fun add(/*0*/ c: C!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class B : A {
public constructor B()
public/*package*/ open override /*1*/ /*fake_override*/ fun add(/*0*/ c: C!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun test(/*0*/ x: kotlin.Any?): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface C {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract fun on(/*0*/ s: kotlin.String!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -19788,6 +19788,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
runTest("compiler/testData/diagnostics/tests/samConversions/checkSamConversionsAreDisabledByDefault.kt");
}
@TestMetadata("conversionOnLambdaAsLastExpression.kt")
public void testConversionOnLambdaAsLastExpression() throws Exception {
runTest("compiler/testData/diagnostics/tests/samConversions/conversionOnLambdaAsLastExpression.kt");
}
@TestMetadata("DisabledForKTSimple.kt")
public void testDisabledForKTSimple() throws Exception {
runTest("compiler/testData/diagnostics/tests/samConversions/DisabledForKTSimple.kt");
@@ -19778,6 +19778,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/samConversions/checkSamConversionsAreDisabledByDefault.kt");
}
@TestMetadata("conversionOnLambdaAsLastExpression.kt")
public void testConversionOnLambdaAsLastExpression() throws Exception {
runTest("compiler/testData/diagnostics/tests/samConversions/conversionOnLambdaAsLastExpression.kt");
}
@TestMetadata("DisabledForKTSimple.kt")
public void testDisabledForKTSimple() throws Exception {
runTest("compiler/testData/diagnostics/tests/samConversions/DisabledForKTSimple.kt");