FIR: postpone callable reference candidate in default argument case

#KT-53019 Fixed
This commit is contained in:
Mikhail Glukhikh
2022-06-29 16:55:41 +02:00
committed by Space
parent c36e160f24
commit c92d685415
14 changed files with 317 additions and 0 deletions
@@ -17721,6 +17721,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/fir/callableReferenceToStaticFunction.kt");
}
@Test
@TestMetadata("cannotCastToFunction.kt")
public void testCannotCastToFunction() throws Exception {
runTest("compiler/testData/codegen/box/fir/cannotCastToFunction.kt");
}
@Test
@TestMetadata("cannotCastToFunctionInIf.kt")
public void testCannotCastToFunctionInIf() throws Exception {
runTest("compiler/testData/codegen/box/fir/cannotCastToFunctionInIf.kt");
}
@Test
@TestMetadata("ClassBuilder.kt")
public void testClassBuilder() throws Exception {
@@ -2494,6 +2494,12 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
runTest("compiler/testData/ir/irText/firProblems/candidateSymbol.kt");
}
@Test
@TestMetadata("cannotCastToFunction.kt")
public void testCannotCastToFunction() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/cannotCastToFunction.kt");
}
@Test
@TestMetadata("ClashResolutionDescriptor.kt")
public void testClashResolutionDescriptor() throws Exception {
@@ -2494,6 +2494,12 @@ public class LightTreeFir2IrTextTestGenerated extends AbstractLightTreeFir2IrTex
runTest("compiler/testData/ir/irText/firProblems/candidateSymbol.kt");
}
@Test
@TestMetadata("cannotCastToFunction.kt")
public void testCannotCastToFunction() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/cannotCastToFunction.kt");
}
@Test
@TestMetadata("ClashResolutionDescriptor.kt")
public void testClashResolutionDescriptor() throws Exception {
@@ -456,6 +456,19 @@ class FirCallResolver(
}
val chosenCandidate = reducedCandidates.single()
if (!resolvedCallableReferenceAtom.hasBeenPostponed &&
expectedType is ConeTypeVariableType &&
chosenCandidate.symbol.fir.let { func ->
func is FirSimpleFunction && func.valueParameters.any { param ->
param.defaultValue != null
}
}
) {
resolvedCallableReferenceAtom.hasBeenPostponed = true
return applicability to true
}
constraintSystemBuilder.runTransaction {
chosenCandidate.outerConstraintBuilderEffect!!(this)
true
@@ -0,0 +1,22 @@
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND: JVM_IR
open class IrElement
fun IrElement.dumpKotlinLike(options: String = ""): String = "O"
fun IrElement.dump(normalizeNames: Boolean = false, stableOrder: Boolean = false): String = "K"
fun <T> select(flag: Boolean, a: T, b: T): T =
if (flag) a else b
fun dump(data: IrElement, dumpStrategy: String): String {
// Note: K1 reports TYPE_MISMATCH here (see also cannotCastToFunctionInIf.kt working both in K1/K2)
val dump: IrElement.() -> String = select(dumpStrategy == "KotlinLike", IrElement::dumpKotlinLike, IrElement::dump)
return data.dump()
}
fun box(): String {
val element = IrElement()
return dump(element, "KotlinLike") + dump(element, "OtherStrategy")
}
@@ -0,0 +1,19 @@
// TARGET_BACKEND: JVM_IR
// See KT-53019
// See also cannotCastToFunction.kt with select instead of if
open class IrElement
fun IrElement.dumpKotlinLike(options: String = ""): String = "O"
fun IrElement.dump(normalizeNames: Boolean = false, stableOrder: Boolean = false): String = "K"
fun dump(data: IrElement, dumpStrategy: String): String {
val dump: IrElement.() -> String = if (dumpStrategy == "KotlinLike") IrElement::dumpKotlinLike else IrElement::dump
return data.dump()
}
fun box(): String {
val element = IrElement()
return dump(element, "KotlinLike") + dump(element, "OtherStrategy")
}
@@ -0,0 +1,69 @@
FILE fqName:<root> fileName:/cannotCastToFunction.kt
CLASS CLASS name:IrElement modality:OPEN visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.IrElement
CONSTRUCTOR visibility:public <> () returnType:<root>.IrElement [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:IrElement modality:OPEN visibility:public superTypes:[kotlin.Any]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN name:dumpKotlinLike visibility:public modality:FINAL <> ($receiver:<root>.IrElement, options:kotlin.String) returnType:kotlin.String
$receiver: VALUE_PARAMETER name:<this> type:<root>.IrElement
VALUE_PARAMETER name:options index:0 type:kotlin.String
EXPRESSION_BODY
CONST String type=kotlin.String value=""
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun dumpKotlinLike (options: kotlin.String): kotlin.String declared in <root>'
CONST String type=kotlin.String value="O"
FUN name:dump visibility:public modality:FINAL <> ($receiver:<root>.IrElement, normalizeNames:kotlin.Boolean, stableOrder:kotlin.Boolean) returnType:kotlin.String
$receiver: VALUE_PARAMETER name:<this> type:<root>.IrElement
VALUE_PARAMETER name:normalizeNames index:0 type:kotlin.Boolean
EXPRESSION_BODY
CONST Boolean type=kotlin.Boolean value=false
VALUE_PARAMETER name:stableOrder index:1 type:kotlin.Boolean
EXPRESSION_BODY
CONST Boolean type=kotlin.Boolean value=false
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun dump (normalizeNames: kotlin.Boolean, stableOrder: kotlin.Boolean): kotlin.String declared in <root>'
CONST String type=kotlin.String value="K"
FUN name:dump visibility:public modality:FINAL <> (data:<root>.IrElement, dumpStrategy:kotlin.String) returnType:kotlin.String
VALUE_PARAMETER name:data index:0 type:<root>.IrElement
VALUE_PARAMETER name:dumpStrategy index:1 type:kotlin.String
BLOCK_BODY
VAR name:dump type:@[ExtensionFunctionType] kotlin.Function1<<root>.IrElement, kotlin.String> [val]
WHEN type=@[ExtensionFunctionType] kotlin.Function1<<root>.IrElement, kotlin.String> origin=IF
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'dumpStrategy: kotlin.String declared in <root>.dump' type=kotlin.String origin=null
arg1: CONST String type=kotlin.String value="KotlinLike"
then: FUN_EXPR type=kotlin.Function1<<root>.IrElement, kotlin.String> origin=ADAPTED_FUNCTION_REFERENCE
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:dumpKotlinLike visibility:local modality:FINAL <> (p0:<root>.IrElement) returnType:kotlin.String
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.IrElement
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun dumpKotlinLike (p0: <root>.IrElement): kotlin.String declared in <root>.dump'
CALL 'public final fun dumpKotlinLike (options: kotlin.String): kotlin.String declared in <root>' type=kotlin.String origin=null
$receiver: GET_VAR 'p0: <root>.IrElement declared in <root>.dump.dumpKotlinLike' type=<root>.IrElement origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: FUN_EXPR type=kotlin.Function1<<root>.IrElement, kotlin.String> origin=ADAPTED_FUNCTION_REFERENCE
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:dump visibility:local modality:FINAL <> (p0:<root>.IrElement) returnType:kotlin.String
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.IrElement
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun dump (p0: <root>.IrElement): kotlin.String declared in <root>.dump'
CALL 'public final fun dump (normalizeNames: kotlin.Boolean, stableOrder: kotlin.Boolean): kotlin.String declared in <root>' type=kotlin.String origin=null
$receiver: GET_VAR 'p0: <root>.IrElement declared in <root>.dump.dump' type=<root>.IrElement origin=null
RETURN type=kotlin.Nothing from='public final fun dump (data: <root>.IrElement, dumpStrategy: kotlin.String): kotlin.String declared in <root>'
CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.String origin=INVOKE
$this: GET_VAR 'val dump: @[ExtensionFunctionType] kotlin.Function1<<root>.IrElement, kotlin.String> [val] declared in <root>.dump' type=@[ExtensionFunctionType] kotlin.Function1<<root>.IrElement, kotlin.String> origin=VARIABLE_AS_FUNCTION
p1: GET_VAR 'data: <root>.IrElement declared in <root>.dump' type=<root>.IrElement origin=null
@@ -0,0 +1,30 @@
open class IrElement {
constructor() /* primary */ {
super/*Any*/()
/* <init>() */
}
}
fun IrElement.dumpKotlinLike(options: String = ""): String {
return "O"
}
fun IrElement.dump(normalizeNames: Boolean = false, stableOrder: Boolean = false): String {
return "K"
}
fun dump(data: IrElement, dumpStrategy: String): String {
val dump: @ExtensionFunctionType Function1<IrElement, String> = when {
EQEQ(arg0 = dumpStrategy, arg1 = "KotlinLike") -> local fun dumpKotlinLike(p0: IrElement): String {
return p0.dumpKotlinLike()
}
else -> local fun dump(p0: IrElement): String {
return p0.dump()
}
}
return dump.invoke(p1 = data)
}
@@ -0,0 +1,71 @@
FILE fqName:<root> fileName:/cannotCastToFunction.kt
CLASS CLASS name:IrElement modality:OPEN visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.IrElement
CONSTRUCTOR visibility:public <> () returnType:<root>.IrElement [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:IrElement modality:OPEN visibility:public superTypes:[kotlin.Any]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN name:dumpKotlinLike visibility:public modality:FINAL <> ($receiver:<root>.IrElement, options:kotlin.String) returnType:kotlin.String
$receiver: VALUE_PARAMETER name:<this> type:<root>.IrElement
VALUE_PARAMETER name:options index:0 type:kotlin.String
EXPRESSION_BODY
CONST String type=kotlin.String value=""
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun dumpKotlinLike (options: kotlin.String): kotlin.String declared in <root>'
CONST String type=kotlin.String value="O"
FUN name:dump visibility:public modality:FINAL <> ($receiver:<root>.IrElement, normalizeNames:kotlin.Boolean, stableOrder:kotlin.Boolean) returnType:kotlin.String
$receiver: VALUE_PARAMETER name:<this> type:<root>.IrElement
VALUE_PARAMETER name:normalizeNames index:0 type:kotlin.Boolean
EXPRESSION_BODY
CONST Boolean type=kotlin.Boolean value=false
VALUE_PARAMETER name:stableOrder index:1 type:kotlin.Boolean
EXPRESSION_BODY
CONST Boolean type=kotlin.Boolean value=false
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun dump (normalizeNames: kotlin.Boolean, stableOrder: kotlin.Boolean): kotlin.String declared in <root>'
CONST String type=kotlin.String value="K"
FUN name:dump visibility:public modality:FINAL <> (data:<root>.IrElement, dumpStrategy:kotlin.String) returnType:kotlin.String
VALUE_PARAMETER name:data index:0 type:<root>.IrElement
VALUE_PARAMETER name:dumpStrategy index:1 type:kotlin.String
BLOCK_BODY
VAR name:dump type:@[ExtensionFunctionType] kotlin.Function1<<root>.IrElement, kotlin.String> [val]
WHEN type=@[ExtensionFunctionType] kotlin.Function1<<root>.IrElement, kotlin.String> origin=IF
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'dumpStrategy: kotlin.String declared in <root>.dump' type=kotlin.String origin=null
arg1: CONST String type=kotlin.String value="KotlinLike"
then: BLOCK type=kotlin.Function1<<root>.IrElement, kotlin.String> origin=ADAPTED_FUNCTION_REFERENCE
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:dumpKotlinLike visibility:local modality:FINAL <> (p0:<root>.IrElement) returnType:kotlin.String
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.IrElement
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun dumpKotlinLike (p0: <root>.IrElement): kotlin.String declared in <root>.dump'
CALL 'public final fun dumpKotlinLike (options: kotlin.String): kotlin.String declared in <root>' type=kotlin.String origin=null
$receiver: GET_VAR 'p0: <root>.IrElement declared in <root>.dump.dumpKotlinLike' type=<root>.IrElement origin=null
FUNCTION_REFERENCE 'local final fun dumpKotlinLike (p0: <root>.IrElement): kotlin.String declared in <root>.dump' type=kotlin.Function1<<root>.IrElement, kotlin.String> origin=ADAPTED_FUNCTION_REFERENCE reflectionTarget=public final fun dumpKotlinLike (options: kotlin.String): kotlin.String declared in <root>
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: BLOCK type=kotlin.Function1<<root>.IrElement, kotlin.String> origin=ADAPTED_FUNCTION_REFERENCE
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:dump visibility:local modality:FINAL <> (p0:<root>.IrElement) returnType:kotlin.String
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.IrElement
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun dump (p0: <root>.IrElement): kotlin.String declared in <root>.dump'
CALL 'public final fun dump (normalizeNames: kotlin.Boolean, stableOrder: kotlin.Boolean): kotlin.String declared in <root>' type=kotlin.String origin=null
$receiver: GET_VAR 'p0: <root>.IrElement declared in <root>.dump.dump' type=<root>.IrElement origin=null
FUNCTION_REFERENCE 'local final fun dump (p0: <root>.IrElement): kotlin.String declared in <root>.dump' type=kotlin.Function1<<root>.IrElement, kotlin.String> origin=ADAPTED_FUNCTION_REFERENCE reflectionTarget=public final fun dump (normalizeNames: kotlin.Boolean, stableOrder: kotlin.Boolean): kotlin.String declared in <root>
RETURN type=kotlin.Nothing from='public final fun dump (data: <root>.IrElement, dumpStrategy: kotlin.String): kotlin.String declared in <root>'
CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.String origin=INVOKE
$this: GET_VAR 'val dump: @[ExtensionFunctionType] kotlin.Function1<<root>.IrElement, kotlin.String> [val] declared in <root>.dump' type=@[ExtensionFunctionType] kotlin.Function1<<root>.IrElement, kotlin.String> origin=VARIABLE_AS_FUNCTION
p1: GET_VAR 'data: <root>.IrElement declared in <root>.dump' type=<root>.IrElement origin=null
@@ -0,0 +1,10 @@
open class IrElement
fun IrElement.dumpKotlinLike(options: String = ""): String = "O"
fun IrElement.dump(normalizeNames: Boolean = false, stableOrder: Boolean = false): String = "K"
fun dump(data: IrElement, dumpStrategy: String): String {
val dump: IrElement.() -> String = if (dumpStrategy == "KotlinLike") IrElement::dumpKotlinLike else IrElement::dump
return data.dump()
}
@@ -0,0 +1,36 @@
open class IrElement {
constructor() /* primary */ {
super/*Any*/()
/* <init>() */
}
}
fun IrElement.dumpKotlinLike(options: String = ""): String {
return "O"
}
fun IrElement.dump(normalizeNames: Boolean = false, stableOrder: Boolean = false): String {
return "K"
}
fun dump(data: IrElement, dumpStrategy: String): String {
val dump: @ExtensionFunctionType Function1<IrElement, String> = when {
EQEQ(arg0 = dumpStrategy, arg1 = "KotlinLike") -> { // BLOCK
local fun dumpKotlinLike(p0: IrElement): String {
return p0.dumpKotlinLike()
}
::dumpKotlinLike
}
else -> { // BLOCK
local fun dump(p0: IrElement): String {
return p0.dump()
}
::dump
}
}
return dump.invoke(p1 = data)
}
@@ -17721,6 +17721,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/fir/callableReferenceToStaticFunction.kt");
}
@Test
@TestMetadata("cannotCastToFunction.kt")
public void testCannotCastToFunction() throws Exception {
runTest("compiler/testData/codegen/box/fir/cannotCastToFunction.kt");
}
@Test
@TestMetadata("cannotCastToFunctionInIf.kt")
public void testCannotCastToFunctionInIf() throws Exception {
runTest("compiler/testData/codegen/box/fir/cannotCastToFunctionInIf.kt");
}
@Test
@TestMetadata("ClassBuilder.kt")
public void testClassBuilder() throws Exception {
@@ -2494,6 +2494,12 @@ public class IrTextTestGenerated extends AbstractIrTextTest {
runTest("compiler/testData/ir/irText/firProblems/candidateSymbol.kt");
}
@Test
@TestMetadata("cannotCastToFunction.kt")
public void testCannotCastToFunction() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/cannotCastToFunction.kt");
}
@Test
@TestMetadata("ClashResolutionDescriptor.kt")
public void testClashResolutionDescriptor() throws Exception {
@@ -1857,6 +1857,11 @@ public class KlibTextTestCaseGenerated extends AbstractKlibTextTestCase {
runTest("compiler/testData/ir/irText/firProblems/candidateSymbol.kt");
}
@TestMetadata("cannotCastToFunction.kt")
public void testCannotCastToFunction() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/cannotCastToFunction.kt");
}
@TestMetadata("DeepCopyIrTree.kt")
public void testDeepCopyIrTree() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/DeepCopyIrTree.kt");