Introduce Unit-conversions for simple arguments
This commit is contained in:
+43
@@ -24444,6 +24444,49 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/unitConversion")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class UnitConversion extends AbstractFirOldFrontendDiagnosticsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInUnitConversion() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/unitConversion"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("chainedFunSuspendUnitConversion.kt")
|
||||||
|
public void testChainedFunSuspendUnitConversion() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedFunSuspendUnitConversion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("chainedFunUnitConversion.kt")
|
||||||
|
public void testChainedFunUnitConversion() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedFunUnitConversion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("chainedUnitSuspendConversion.kt")
|
||||||
|
public void testChainedUnitSuspendConversion() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedUnitSuspendConversion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unitConversionCompatibility.kt")
|
||||||
|
public void testUnitConversionCompatibility() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionCompatibility.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unitConversionForAllKinds.kt")
|
||||||
|
public void testUnitConversionForAllKinds() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionForAllKinds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unitConversionForSubtypes.kt")
|
||||||
|
public void testUnitConversionForSubtypes() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionForSubtypes.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/varargs")
|
@TestMetadata("compiler/testData/diagnostics/tests/varargs")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+83
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.resolve.calls.components
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.LowerPriorityToPreserveCompatibility
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinResolutionCandidate
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
|
import org.jetbrains.kotlin.types.isDynamic
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
|
|
||||||
|
object UnitTypeConversions : ParameterTypeConversion {
|
||||||
|
override fun conversionDefinitelyNotNeeded(
|
||||||
|
candidate: KotlinResolutionCandidate,
|
||||||
|
argument: KotlinCallArgument,
|
||||||
|
expectedParameterType: UnwrappedType
|
||||||
|
): Boolean {
|
||||||
|
// for callable references and lambdas it already works
|
||||||
|
if (argument !is SimpleKotlinCallArgument) return true
|
||||||
|
|
||||||
|
val receiver = argument.receiver
|
||||||
|
if (receiver.receiverValue.type.hasUnitOrDynamicReturnType()) return true
|
||||||
|
if (receiver.typesFromSmartCasts.any { it.hasUnitOrDynamicReturnType() }) return true
|
||||||
|
|
||||||
|
if (
|
||||||
|
!expectedParameterType.isBuiltinFunctionalType ||
|
||||||
|
!expectedParameterType.getReturnTypeFromFunctionType().isUnit()
|
||||||
|
) return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KotlinType.hasUnitOrDynamicReturnType(): Boolean =
|
||||||
|
isFunctionOrKFunctionTypeWithAnySuspendability && arguments.last().type.isUnitOrDynamic()
|
||||||
|
|
||||||
|
private fun KotlinType.isUnitOrDynamic(): Boolean = isUnit() || isDynamic()
|
||||||
|
|
||||||
|
override fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean =
|
||||||
|
argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionType
|
||||||
|
|
||||||
|
override fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean {
|
||||||
|
if (argument !is SimpleKotlinCallArgument) return false
|
||||||
|
|
||||||
|
var isFunctionTypeOrSubtype = false
|
||||||
|
val hasReturnTypeInSubtypes = argument.receiver.stableType.isFunctionTypeOrSubtype {
|
||||||
|
isFunctionTypeOrSubtype = true
|
||||||
|
it.getReturnTypeFromFunctionType().isUnitOrDynamic()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isFunctionTypeOrSubtype) return false
|
||||||
|
|
||||||
|
return !hasReturnTypeInSubtypes
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun convertParameterType(
|
||||||
|
candidate: KotlinResolutionCandidate,
|
||||||
|
argument: KotlinCallArgument,
|
||||||
|
parameter: ParameterDescriptor,
|
||||||
|
expectedParameterType: UnwrappedType
|
||||||
|
): UnwrappedType? {
|
||||||
|
val nonUnitReturnedParameterType = createFunctionType(
|
||||||
|
candidate.callComponents.builtIns,
|
||||||
|
expectedParameterType.annotations,
|
||||||
|
expectedParameterType.getReceiverTypeFromFunctionType(),
|
||||||
|
expectedParameterType.getValueParameterTypesFromFunctionType().map { it.type },
|
||||||
|
parameterNames = null,
|
||||||
|
candidate.callComponents.builtIns.nullableAnyType,
|
||||||
|
suspendFunction = expectedParameterType.isSuspendFunctionType
|
||||||
|
)
|
||||||
|
|
||||||
|
candidate.addDiagnostic(LowerPriorityToPreserveCompatibility)
|
||||||
|
|
||||||
|
return nonUnitReturnedParameterType
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+18
-6
@@ -40,14 +40,23 @@ object TypeConversions {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val suspendConversionData = performConversionBeforeSubtyping(
|
val suspendConversionData = performConversionBeforeSubtyping(
|
||||||
candidate, argument, candidateParameter, samConversionData.convertedType ?: candidateExpectedType, SuspendTypeConversions
|
candidate, argument, candidateParameter,
|
||||||
|
candidateExpectedType = samConversionData.convertedType ?: candidateExpectedType,
|
||||||
|
SuspendTypeConversions
|
||||||
|
)
|
||||||
|
|
||||||
|
val unitConversionData = performConversionBeforeSubtyping(
|
||||||
|
candidate, argument, candidateParameter,
|
||||||
|
candidateExpectedType = suspendConversionData.convertedType ?: samConversionData.convertedType ?: candidateExpectedType,
|
||||||
|
UnitTypeConversions
|
||||||
)
|
)
|
||||||
|
|
||||||
return ConversionData(
|
return ConversionData(
|
||||||
convertedType = suspendConversionData.convertedType ?: samConversionData.convertedType,
|
convertedType = unitConversionData.convertedType ?: suspendConversionData.convertedType ?: samConversionData.convertedType,
|
||||||
wasConversion = samConversionData.wasConversion || suspendConversionData.wasConversion,
|
wasConversion = samConversionData.wasConversion || suspendConversionData.wasConversion || unitConversionData.wasConversion,
|
||||||
conversionDefinitelyNotNeeded = samConversionData.conversionDefinitelyNotNeeded &&
|
conversionDefinitelyNotNeeded = samConversionData.conversionDefinitelyNotNeeded &&
|
||||||
suspendConversionData.conversionDefinitelyNotNeeded
|
suspendConversionData.conversionDefinitelyNotNeeded &&
|
||||||
|
unitConversionData.conversionDefinitelyNotNeeded
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,10 +69,13 @@ object TypeConversions {
|
|||||||
val samConvertedType = performConversionAfterSubtyping(
|
val samConvertedType = performConversionAfterSubtyping(
|
||||||
candidate, argument, candidateParameter, candidateExpectedType, SamTypeConversions
|
candidate, argument, candidateParameter, candidateExpectedType, SamTypeConversions
|
||||||
)
|
)
|
||||||
|
|
||||||
if (samConvertedType != null) return samConvertedType
|
if (samConvertedType != null) return samConvertedType
|
||||||
|
|
||||||
return performConversionAfterSubtyping(candidate, argument, candidateParameter, candidateExpectedType, SuspendTypeConversions)
|
val suspendConvertedType =
|
||||||
|
performConversionAfterSubtyping(candidate, argument, candidateParameter, candidateExpectedType, SuspendTypeConversions)
|
||||||
|
if (suspendConvertedType != null) return suspendConvertedType
|
||||||
|
|
||||||
|
return performConversionAfterSubtyping(candidate, argument, candidateParameter, candidateExpectedType, UnitTypeConversions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun performConversionAfterSubtyping(
|
private fun performConversionAfterSubtyping(
|
||||||
|
|||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// !LANGUAGE: +UnitConversion +SuspendConversion
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||||
|
|
||||||
|
fun interface SuspendRunnable {
|
||||||
|
suspend fun run()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(r: SuspendRunnable) {}
|
||||||
|
|
||||||
|
fun bar(): String = ""
|
||||||
|
|
||||||
|
abstract class SubInt : () -> Int
|
||||||
|
|
||||||
|
fun test(f: () -> String, s: SubInt) {
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>foo<!>(f)
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>foo<!>(s)
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>foo<!>(::bar)
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// !LANGUAGE: +UnitConversion +SuspendConversion
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||||
|
|
||||||
|
fun interface SuspendRunnable {
|
||||||
|
suspend fun run()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(r: SuspendRunnable) {}
|
||||||
|
|
||||||
|
fun bar(): String = ""
|
||||||
|
|
||||||
|
abstract class SubInt : () -> Int
|
||||||
|
|
||||||
|
fun test(f: () -> String, s: SubInt) {
|
||||||
|
foo(f)
|
||||||
|
foo(s)
|
||||||
|
foo(::bar)
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun bar(): kotlin.String
|
||||||
|
public fun foo(/*0*/ r: SuspendRunnable): kotlin.Unit
|
||||||
|
public fun test(/*0*/ f: () -> kotlin.String, /*1*/ s: SubInt): kotlin.Unit
|
||||||
|
|
||||||
|
public abstract class SubInt : () -> kotlin.Int {
|
||||||
|
public constructor SubInt()
|
||||||
|
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 override /*1*/ /*fake_override*/ fun invoke(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun interface SuspendRunnable {
|
||||||
|
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 suspend fun run(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// !LANGUAGE: +UnitConversion
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||||
|
|
||||||
|
fun interface KRunnable {
|
||||||
|
fun run()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(r: KRunnable) {}
|
||||||
|
|
||||||
|
abstract class SubInt : () -> Int
|
||||||
|
|
||||||
|
fun test(f: () -> Int, s: SubInt) {
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>foo<!>(f)
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>foo<!>(s)
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// !LANGUAGE: +UnitConversion
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||||
|
|
||||||
|
fun interface KRunnable {
|
||||||
|
fun run()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(r: KRunnable) {}
|
||||||
|
|
||||||
|
abstract class SubInt : () -> Int
|
||||||
|
|
||||||
|
fun test(f: () -> Int, s: SubInt) {
|
||||||
|
foo(f)
|
||||||
|
foo(s)
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo(/*0*/ r: KRunnable): kotlin.Unit
|
||||||
|
public fun test(/*0*/ f: () -> kotlin.Int, /*1*/ s: SubInt): kotlin.Unit
|
||||||
|
|
||||||
|
public fun interface KRunnable {
|
||||||
|
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 run(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class SubInt : () -> kotlin.Int {
|
||||||
|
public constructor SubInt()
|
||||||
|
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 override /*1*/ /*fake_override*/ fun invoke(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
// !LANGUAGE: +UnitConversion +SuspendConversion
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||||
|
|
||||||
|
fun foo(f: suspend () -> Unit) {}
|
||||||
|
|
||||||
|
fun bar(): String = ""
|
||||||
|
|
||||||
|
abstract class SubInt : () -> Int
|
||||||
|
|
||||||
|
fun test(g: () -> Double, s: SubInt) {
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>foo<!>(::bar)
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>foo<!>(g)
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>foo<!>(s)
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
// !LANGUAGE: +UnitConversion +SuspendConversion
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||||
|
|
||||||
|
fun foo(f: suspend () -> Unit) {}
|
||||||
|
|
||||||
|
fun bar(): String = ""
|
||||||
|
|
||||||
|
abstract class SubInt : () -> Int
|
||||||
|
|
||||||
|
fun test(g: () -> Double, s: SubInt) {
|
||||||
|
foo(::bar)
|
||||||
|
foo(g)
|
||||||
|
foo(s)
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun bar(): kotlin.String
|
||||||
|
public fun foo(/*0*/ f: suspend () -> kotlin.Unit): kotlin.Unit
|
||||||
|
public fun test(/*0*/ g: () -> kotlin.Double, /*1*/ s: SubInt): kotlin.Unit
|
||||||
|
|
||||||
|
public abstract class SubInt : () -> kotlin.Int {
|
||||||
|
public constructor SubInt()
|
||||||
|
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 override /*1*/ /*fake_override*/ fun invoke(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// !LANGUAGE: +UnitConversion
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||||
|
|
||||||
|
fun foo(f: () -> Unit) {}
|
||||||
|
fun <T> fooGeneric(f: (T) -> Unit): T = TODO()
|
||||||
|
|
||||||
|
fun bar(): String = ""
|
||||||
|
fun createCall(): () -> Int = TODO()
|
||||||
|
|
||||||
|
fun test(g: () -> String, h: (Float) -> String) {
|
||||||
|
foo(::bar)
|
||||||
|
foo { "something" }
|
||||||
|
foo(g)
|
||||||
|
|
||||||
|
fooGeneric(h)
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// !LANGUAGE: +UnitConversion
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||||
|
|
||||||
|
fun foo(f: () -> Unit) {}
|
||||||
|
fun <T> fooGeneric(f: (T) -> Unit): T = TODO()
|
||||||
|
|
||||||
|
fun bar(): String = ""
|
||||||
|
fun createCall(): () -> Int = TODO()
|
||||||
|
|
||||||
|
fun test(g: () -> String, h: (Float) -> String) {
|
||||||
|
foo(::bar)
|
||||||
|
foo { "something" }
|
||||||
|
foo(g)
|
||||||
|
|
||||||
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Float")!>fooGeneric(h)<!>
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun bar(): kotlin.String
|
||||||
|
public fun createCall(): () -> kotlin.Int
|
||||||
|
public fun foo(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
|
||||||
|
public fun </*0*/ T> fooGeneric(/*0*/ f: (T) -> kotlin.Unit): T
|
||||||
|
public fun test(/*0*/ g: () -> kotlin.String, /*1*/ h: (kotlin.Float) -> kotlin.String): kotlin.Unit
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// !LANGUAGE: +UnitConversion
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||||
|
|
||||||
|
fun foo(f: (Int, String) -> Unit) {}
|
||||||
|
|
||||||
|
abstract class SubInt : (Int, String) -> Int
|
||||||
|
abstract class SubIntWrong : (String, String) -> Int
|
||||||
|
|
||||||
|
fun test1(s: SubInt, sWrong: SubIntWrong) {
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>foo<!>(s)
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>foo<!>(sWrong)
|
||||||
|
|
||||||
|
val a = "foo"
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>foo<!>(a)
|
||||||
|
|
||||||
|
a as (Int, String) -> String
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>foo<!>(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> test2(x: T) where T : (Int, String) -> Int, T : (Double) -> Int {
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>foo<!>(x)
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// !LANGUAGE: +UnitConversion
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||||
|
|
||||||
|
fun foo(f: (Int, String) -> Unit) {}
|
||||||
|
|
||||||
|
abstract class SubInt : (Int, String) -> Int
|
||||||
|
abstract class SubIntWrong : (String, String) -> Int
|
||||||
|
|
||||||
|
fun test1(s: SubInt, sWrong: SubIntWrong) {
|
||||||
|
foo(s)
|
||||||
|
foo(<!TYPE_MISMATCH!>sWrong<!>)
|
||||||
|
|
||||||
|
val a = "foo"
|
||||||
|
foo(<!TYPE_MISMATCH!>a<!>)
|
||||||
|
|
||||||
|
a <!CAST_NEVER_SUCCEEDS!>as<!> (Int, String) -> String
|
||||||
|
foo(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> test2(x: T) where T : (Int, String) -> Int, T : (Double) -> Int {
|
||||||
|
foo(x)
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo(/*0*/ f: (kotlin.Int, kotlin.String) -> kotlin.Unit): kotlin.Unit
|
||||||
|
public fun test1(/*0*/ s: SubInt, /*1*/ sWrong: SubIntWrong): kotlin.Unit
|
||||||
|
public fun </*0*/ T : (kotlin.Int, kotlin.String) -> kotlin.Int> test2(/*0*/ x: T): kotlin.Unit where T : (kotlin.Double) -> kotlin.Int
|
||||||
|
|
||||||
|
public abstract class SubInt : (kotlin.Int, kotlin.String) -> kotlin.Int {
|
||||||
|
public constructor SubInt()
|
||||||
|
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 override /*1*/ /*fake_override*/ fun invoke(/*0*/ p1: kotlin.Int, /*1*/ p2: kotlin.String): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class SubIntWrong : (kotlin.String, kotlin.String) -> kotlin.Int {
|
||||||
|
public constructor SubIntWrong()
|
||||||
|
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 override /*1*/ /*fake_override*/ fun invoke(/*0*/ p1: kotlin.String, /*1*/ p2: kotlin.String): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -24526,6 +24526,49 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/unitConversion")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class UnitConversion extends AbstractDiagnosticsTestWithFirValidation {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInUnitConversion() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/unitConversion"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("chainedFunSuspendUnitConversion.kt")
|
||||||
|
public void testChainedFunSuspendUnitConversion() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedFunSuspendUnitConversion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("chainedFunUnitConversion.kt")
|
||||||
|
public void testChainedFunUnitConversion() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedFunUnitConversion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("chainedUnitSuspendConversion.kt")
|
||||||
|
public void testChainedUnitSuspendConversion() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedUnitSuspendConversion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unitConversionCompatibility.kt")
|
||||||
|
public void testUnitConversionCompatibility() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionCompatibility.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unitConversionForAllKinds.kt")
|
||||||
|
public void testUnitConversionForAllKinds() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionForAllKinds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unitConversionForSubtypes.kt")
|
||||||
|
public void testUnitConversionForSubtypes() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionForSubtypes.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/varargs")
|
@TestMetadata("compiler/testData/diagnostics/tests/varargs")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Generated
+43
@@ -24446,6 +24446,49 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/unitConversion")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class UnitConversion extends AbstractDiagnosticsUsingJavacTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInUnitConversion() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/unitConversion"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("chainedFunSuspendUnitConversion.kt")
|
||||||
|
public void testChainedFunSuspendUnitConversion() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedFunSuspendUnitConversion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("chainedFunUnitConversion.kt")
|
||||||
|
public void testChainedFunUnitConversion() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedFunUnitConversion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("chainedUnitSuspendConversion.kt")
|
||||||
|
public void testChainedUnitSuspendConversion() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedUnitSuspendConversion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unitConversionCompatibility.kt")
|
||||||
|
public void testUnitConversionCompatibility() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionCompatibility.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unitConversionForAllKinds.kt")
|
||||||
|
public void testUnitConversionForAllKinds() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionForAllKinds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unitConversionForSubtypes.kt")
|
||||||
|
public void testUnitConversionForSubtypes() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionForSubtypes.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/varargs")
|
@TestMetadata("compiler/testData/diagnostics/tests/varargs")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ enum class LanguageFeature(
|
|||||||
FunctionReferenceWithDefaultValueAsOtherType(sinceVersion = KOTLIN_1_4),
|
FunctionReferenceWithDefaultValueAsOtherType(sinceVersion = KOTLIN_1_4),
|
||||||
NonStrictOnlyInputTypesChecks(sinceVersion = KOTLIN_1_4),
|
NonStrictOnlyInputTypesChecks(sinceVersion = KOTLIN_1_4),
|
||||||
SuspendConversion(sinceVersion = KOTLIN_1_4, defaultState = State.DISABLED),
|
SuspendConversion(sinceVersion = KOTLIN_1_4, defaultState = State.DISABLED),
|
||||||
|
UnitConversion(sinceVersion = KOTLIN_1_4, defaultState = State.DISABLED),
|
||||||
OverloadResolutionByLambdaReturnType(sinceVersion = KOTLIN_1_4),
|
OverloadResolutionByLambdaReturnType(sinceVersion = KOTLIN_1_4),
|
||||||
|
|
||||||
BooleanElvisBoundSmartCasts(sinceVersion = KOTLIN_1_3, defaultState = State.DISABLED), // see KT-26357 for details
|
BooleanElvisBoundSmartCasts(sinceVersion = KOTLIN_1_3, defaultState = State.DISABLED), // see KT-26357 for details
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ val KotlinType.isSuspendFunctionTypeOrSubtype: Boolean
|
|||||||
val KotlinType.isBuiltinFunctionalTypeOrSubtype: Boolean
|
val KotlinType.isBuiltinFunctionalTypeOrSubtype: Boolean
|
||||||
get() = isTypeOrSubtypeOf { it.isBuiltinFunctionalType }
|
get() = isTypeOrSubtypeOf { it.isBuiltinFunctionalType }
|
||||||
|
|
||||||
|
fun KotlinType.isFunctionTypeOrSubtype(predicate: (KotlinType) -> Boolean): Boolean =
|
||||||
|
isTypeOrSubtypeOf { it.isFunctionType && predicate(it) }
|
||||||
|
|
||||||
val KotlinType.isFunctionType: Boolean
|
val KotlinType.isFunctionType: Boolean
|
||||||
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionClassDescriptor.Kind.Function
|
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionClassDescriptor.Kind.Function
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user