K2: apply SAM if argument has postponed lambdas #KT-53966 Fixed
This commit is contained in:
committed by
Space Team
parent
5a9e8b3c0a
commit
898a9a0f2c
+6
@@ -27578,6 +27578,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/testData/diagnostics/tests/samConversions/samConversionWithCondition.kt");
|
runTest("compiler/testData/diagnostics/tests/samConversions/samConversionWithCondition.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("samConversionWithConditionJava.kt")
|
||||||
|
public void testSamConversionWithConditionJava() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/samConversions/samConversionWithConditionJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("samConversionsWithSmartCasts.kt")
|
@TestMetadata("samConversionsWithSmartCasts.kt")
|
||||||
public void testSamConversionsWithSmartCasts() throws Exception {
|
public void testSamConversionsWithSmartCasts() throws Exception {
|
||||||
|
|||||||
+6
@@ -27590,6 +27590,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/samConversions/samConversionWithCondition.kt");
|
runTest("compiler/testData/diagnostics/tests/samConversions/samConversionWithCondition.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("samConversionWithConditionJava.kt")
|
||||||
|
public void testSamConversionWithConditionJava() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/samConversions/samConversionWithConditionJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("samConversionsWithSmartCasts.kt")
|
@TestMetadata("samConversionsWithSmartCasts.kt")
|
||||||
public void testSamConversionsWithSmartCasts() throws Exception {
|
public void testSamConversionsWithSmartCasts() throws Exception {
|
||||||
|
|||||||
+6
@@ -27578,6 +27578,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/samConversions/samConversionWithCondition.kt");
|
runTest("compiler/testData/diagnostics/tests/samConversions/samConversionWithCondition.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("samConversionWithConditionJava.kt")
|
||||||
|
public void testSamConversionWithConditionJava() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/samConversions/samConversionWithConditionJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("samConversionsWithSmartCasts.kt")
|
@TestMetadata("samConversionsWithSmartCasts.kt")
|
||||||
public void testSamConversionsWithSmartCasts() throws Exception {
|
public void testSamConversionsWithSmartCasts() throws Exception {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
|||||||
import org.jetbrains.kotlin.fir.resolve.createFunctionType
|
import org.jetbrains.kotlin.fir.resolve.createFunctionType
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.unwrapSmartcastExpression
|
import org.jetbrains.kotlin.fir.resolve.dfa.unwrapSmartcastExpression
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.inference.LambdaWithTypeVariableAsExpectedTypeAtom
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPosition
|
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPosition
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeReceiverConstraintPosition
|
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeReceiverConstraintPosition
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.preprocessCallableReference
|
import org.jetbrains.kotlin.fir.resolve.inference.preprocessCallableReference
|
||||||
@@ -38,6 +39,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystem
|
|||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.types.model.CaptureStatus
|
import org.jetbrains.kotlin.types.model.CaptureStatus
|
||||||
import org.jetbrains.kotlin.types.model.TypeSystemCommonSuperTypesContext
|
import org.jetbrains.kotlin.types.model.TypeSystemCommonSuperTypesContext
|
||||||
|
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
|
|
||||||
val SAM_LOOKUP_NAME = Name.special("<SAM-CONSTRUCTOR>")
|
val SAM_LOOKUP_NAME = Name.special("<SAM-CONSTRUCTOR>")
|
||||||
@@ -525,6 +527,16 @@ fun FirExpression.isFunctional(
|
|||||||
if (classLikeExpectedFunctionType == null || coneType is ConeIntegerLiteralType) {
|
if (classLikeExpectedFunctionType == null || coneType is ConeIntegerLiteralType) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val namedReferenceWithCandidate = namedReferenceWithCandidate()
|
||||||
|
if (namedReferenceWithCandidate?.candidate?.postponedAtoms?.any {
|
||||||
|
it is LambdaWithTypeVariableAsExpectedTypeAtom &&
|
||||||
|
it.expectedType.typeConstructor(session.typeContext) == coneType.typeConstructor(session.typeContext)
|
||||||
|
} == true
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
val invokeSymbol =
|
val invokeSymbol =
|
||||||
coneType.findContributedInvokeSymbol(
|
coneType.findContributedInvokeSymbol(
|
||||||
session, scopeSession, classLikeExpectedFunctionType, shouldCalculateReturnTypesOfFakeOverrides = false
|
session, scopeSession, classLikeExpectedFunctionType, shouldCalculateReturnTypesOfFakeOverrides = false
|
||||||
@@ -567,6 +579,13 @@ fun FirExpression.isFunctional(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirExpression.namedReferenceWithCandidate(): FirNamedReferenceWithCandidate? =
|
||||||
|
when (this) {
|
||||||
|
is FirResolvable -> calleeReference as? FirNamedReferenceWithCandidate
|
||||||
|
is FirSafeCallExpression -> (selector as? FirExpression)?.namedReferenceWithCandidate()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
fun FirExpression.getExpectedType(
|
fun FirExpression.getExpectedType(
|
||||||
parameter: FirValueParameter/*, languageVersionSettings: LanguageVersionSettings*/
|
parameter: FirValueParameter/*, languageVersionSettings: LanguageVersionSettings*/
|
||||||
): ConeKotlinType {
|
): ConeKotlinType {
|
||||||
|
|||||||
Vendored
-18
@@ -1,18 +0,0 @@
|
|||||||
// 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 { <!ARGUMENT_TYPE_MISMATCH!>{ _ : String -> Unit }<!> })
|
|
||||||
add(x?.let { <!ARGUMENT_TYPE_MISMATCH!>{ _ : String -> Unit }<!> })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> foo(f: () -> T): T = f()
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// FILE: C.java
|
// FILE: C.java
|
||||||
|
|
||||||
public interface C { void on(String s); }
|
public interface C { void on(String s); }
|
||||||
|
|||||||
+34
-2
@@ -1,10 +1,42 @@
|
|||||||
fun main() {
|
fun main(arg: Nothing?) {
|
||||||
val flag = true
|
val flag = true
|
||||||
consumeTicker(
|
consumeTicker(
|
||||||
if (flag) null else <!ARGUMENT_TYPE_MISMATCH!>{ num -> num.<!UNRESOLVED_REFERENCE!>dec<!>() }<!>
|
if (flag) null else { num -> num.dec() }
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
select({ num -> num.dec() }, null)
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
try { { num -> num.dec() } } catch (e: Exception) { null }
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
arg ?: { num -> num.dec() }
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
if (!flag) ::tick else null
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
select(::tick, null)
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
select(if (flag) null else ::tick, null)
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
// In fact ::tick is not used here
|
||||||
|
try { null } finally { ::tick }
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
try { null } catch (e: Exception) { null } catch (e: Throwable) { ::tick }
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
arg ?: ::tick
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun tick(num: Int) {}
|
||||||
|
|
||||||
|
fun <T> select(a: T, b: T): T = a
|
||||||
|
|
||||||
fun consumeTicker(ticker: Ticker?) {
|
fun consumeTicker(ticker: Ticker?) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-1
@@ -1,10 +1,42 @@
|
|||||||
fun main() {
|
fun main(arg: Nothing?) {
|
||||||
val flag = true
|
val flag = true
|
||||||
consumeTicker(
|
consumeTicker(
|
||||||
if (flag) null else { num -> num.dec() }
|
if (flag) null else { num -> num.dec() }
|
||||||
)
|
)
|
||||||
|
consumeTicker(
|
||||||
|
select({ num -> num.dec() }, null)
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
try { { num -> num.dec() } } catch (e: Exception) { null }
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
<!DEBUG_INFO_CONSTANT!>arg<!> ?: { num -> num.dec() }
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
if (!flag) ::tick else null
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
select(::tick, null)
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
select(if (flag) null else ::tick, null)
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
// In fact ::tick is not used here
|
||||||
|
try { null } finally { ::tick }
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
try { null } catch (e: Exception) { null } catch (e: Throwable) { ::tick }
|
||||||
|
)
|
||||||
|
consumeTicker(
|
||||||
|
<!DEBUG_INFO_CONSTANT!>arg<!> ?: ::tick
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun tick(num: Int) {}
|
||||||
|
|
||||||
|
fun <T> select(a: T, b: T): T = a
|
||||||
|
|
||||||
fun consumeTicker(ticker: Ticker?) {
|
fun consumeTicker(ticker: Ticker?) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -1,7 +1,9 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
public fun consumeTicker(/*0*/ ticker: Ticker?): kotlin.Unit
|
public fun consumeTicker(/*0*/ ticker: Ticker?): kotlin.Unit
|
||||||
public fun main(): kotlin.Unit
|
public fun main(/*0*/ arg: kotlin.Nothing?): kotlin.Unit
|
||||||
|
public fun </*0*/ T> select(/*0*/ a: T, /*1*/ b: T): T
|
||||||
|
public fun tick(/*0*/ num: kotlin.Int): kotlin.Unit
|
||||||
|
|
||||||
public fun interface Ticker {
|
public fun interface Ticker {
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
@@ -9,3 +11,4 @@ public fun interface Ticker {
|
|||||||
public abstract fun tick(/*0*/ num: kotlin.Int): kotlin.Unit
|
public abstract fun tick(/*0*/ num: kotlin.Int): kotlin.Unit
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// FILE: Ticker.java
|
||||||
|
|
||||||
|
public interface Ticker {
|
||||||
|
String tick(String s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Tickers.java
|
||||||
|
|
||||||
|
public class Tickers {
|
||||||
|
public static void consumeTicker(Ticker ticker) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Selectors.java
|
||||||
|
|
||||||
|
public class Selectors {
|
||||||
|
public static <T> T select(T a, T b) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun main(flag: Boolean) {
|
||||||
|
Tickers.consumeTicker(if (flag) null else { s -> s + s })
|
||||||
|
|
||||||
|
Tickers.consumeTicker(Selectors.select({ s -> s + s }, null))
|
||||||
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun main(/*0*/ flag: kotlin.Boolean): kotlin.Unit
|
||||||
|
|
||||||
|
public open class Selectors {
|
||||||
|
public constructor Selectors()
|
||||||
|
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
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public open fun </*0*/ T : kotlin.Any!> select(/*0*/ a: T!, /*1*/ b: T!): T!
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Ticker {
|
||||||
|
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 tick(/*0*/ s: kotlin.String!): kotlin.String!
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class Tickers {
|
||||||
|
public constructor Tickers()
|
||||||
|
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
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public open fun consumeTicker(/*0*/ ticker: Ticker!): kotlin.Unit
|
||||||
|
}
|
||||||
Generated
+6
@@ -27590,6 +27590,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/samConversions/samConversionWithCondition.kt");
|
runTest("compiler/testData/diagnostics/tests/samConversions/samConversionWithCondition.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("samConversionWithConditionJava.kt")
|
||||||
|
public void testSamConversionWithConditionJava() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/samConversions/samConversionWithConditionJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("samConversionsWithSmartCasts.kt")
|
@TestMetadata("samConversionsWithSmartCasts.kt")
|
||||||
public void testSamConversionsWithSmartCasts() throws Exception {
|
public void testSamConversionsWithSmartCasts() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user