[FIR] Properly handle callable references which were resolved with error

This commit is contained in:
Dmitriy Novozhilov
2021-04-15 14:06:30 +03:00
parent 450fb5e915
commit e869f8091a
74 changed files with 377 additions and 312 deletions
@@ -18,10 +18,10 @@ FILE: errCallable.kt
}
public final fun foo(): R|kotlin/Unit| {
lval x: <ERROR TYPE REF: No result type for initializer> = ::<Unresolved name: Nested>#
lval x: R|ERROR CLASS: Unresolved reference: Nested| = ::<Unresolved reference: Nested>#
}
}
public final fun R|Your|.foo(): R|kotlin/Unit| {
lval x: <ERROR TYPE REF: No result type for initializer> = ::<Unresolved name: Nested>#
lval x: R|ERROR CLASS: Unresolved reference: Nested| = ::<Unresolved reference: Nested>#
}
@@ -0,0 +1,25 @@
FILE: leakedImplicitType.kt
public final class Foo : R|kotlin/Any| {
public constructor(): R|Foo| {
super<R|kotlin/Any|>()
}
public final fun bar(): R|kotlin/Unit| {
}
public final fun f(): R|ERROR CLASS: Unresolved reference: bar| {
^f <Unresolved name: Unresolved>#()::<Unresolved reference: bar>#
}
}
public abstract interface IA : R|kotlin/Any| {
}
public abstract interface IB : R|IA| {
}
public final fun R|IA|.extFun(x: R|IB|): R|kotlin/Unit| {
}
public final fun R|IB|.extFun(x: R|IA|): R|kotlin/Unit| {
}
public final fun testWithExpectedType(): R|kotlin/Unit| {
lval extFun_AA_B: R|IA.(IA) -> kotlin/Unit| = Q|IB|::<Unresolved reference: extFun>#
}
@@ -0,0 +1,18 @@
// ISSUE: KT-46072
// Case 1
class Foo {
fun bar() {}
fun f() = <!UNRESOLVED_REFERENCE!>Unresolved<!>()::bar // Type of Unresolved()::bar is implicit
}
// Case 2
interface IA
interface IB : IA
fun IA.extFun(x: IB) {}
fun IB.extFun(x: IA) {}
fun testWithExpectedType() {
val extFun_AA_B: IA.(IA) -> Unit = IB::<!UNRESOLVED_REFERENCE!>extFun<!> // extFun is unresolved, type of IB::extFun is implicit
}
@@ -40,8 +40,8 @@ FILE: referenceToExtension.kt
}
public final fun test_2(): R|kotlin/Unit| {
lval extensionValRef: <ERROR TYPE REF: No result type for initializer> = Q|GenericTest.B|::<Unresolved name: extensionVal>#
lval extensionFunRef: <ERROR TYPE REF: No result type for initializer> = Q|GenericTest.B|::<Unresolved name: extensionFun>#
lval extensionValRef: R|ERROR CLASS: Unresolved reference: extensionVal| = Q|GenericTest.B|::<Unresolved reference: extensionVal>#
lval extensionFunRef: R|ERROR CLASS: Unresolved reference: extensionFun| = Q|GenericTest.B|::<Unresolved reference: extensionFun>#
}
}
@@ -0,0 +1,13 @@
FILE: referenceToField.kt
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final val x: R|kotlin/Int| = Int(1)
public get(): R|kotlin/Int| {
::F|/A.x|
^ this@R|/A|.F|/A.x|
}
}
@@ -0,0 +1,7 @@
class A {
val x: Int = 1
get() {
::<!UNSUPPORTED!>field<!>
return field
}
}
@@ -13,7 +13,7 @@ FILE: beyoundCalls.kt
}
public final fun foo(): R|kotlin/Unit| {
lval x: R|(kotlin/String) -> kotlin/Int| = ::R|/bar|
lval y: <ERROR TYPE REF: No result type for initializer> = ::<Unresolved reference: bar>#
lval y: R|ERROR CLASS: Ambiguity: bar, [/bar, /bar]| = ::<Ambiguity: bar, [/bar, /bar]>#
lval z: R|kotlin/reflect/KFunction1<kotlin/String, kotlin/Int>| = ::R|/baz|
lval w: R|(kotlin/String) -> kotlin/Int| = ::R|/foobaz<kotlin/String, kotlin/Int>|
::R|/baz|
@@ -6,7 +6,7 @@ fun <T, R> foobaz(x: T): R = TODO()
fun foo() {
val x: (String) -> Int = ::bar
val y = ::<!UNRESOLVED_REFERENCE!>bar<!>
val y = ::<!OVERLOAD_RESOLUTION_AMBIGUITY!>bar<!>
val z = ::baz
val w: (String) -> Int = ::foobaz
@@ -6,5 +6,5 @@ FILE: ambiguityWhenNoApplicableCallableReferenceCandidate.kt
public final fun <T> bar(f: R|(T) -> kotlin/Unit|): R|kotlin/Unit| {
}
public final fun test(): R|kotlin/Unit| {
R|/bar|<R|kotlin/Any?|>(::<Unresolved reference: foo>#)
R|/bar|<R|kotlin/Any?|>(::<Ambiguity: foo, [/foo, /foo]>#)
}
@@ -4,5 +4,5 @@ fun foo(y: String) {}
fun <T> bar(f: (T) -> Unit) {}
fun test() {
bar(::<!UNRESOLVED_REFERENCE!>foo<!>)
bar(::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>)
}
@@ -37,7 +37,7 @@ FILE: chooseCallableReferenceDependingOnInferredReceiver.kt
lval a: R|A| = R|/bar|<R|A|>(::R|/A.foo|)
lval b: R|B| = R|/bar|<R|B|>(::R|/B.foo|)
lval t3: R|B| = R|/bar|<R|B|>(::R|/B.baz|)
^ R|/bar|<R|kotlin/Nothing|>(::<Unresolved reference: foo>#)
^ R|/bar|<R|kotlin/Nothing|>(::<Ambiguity: foo, [/B.foo, /B.foo]>#)
}
)
}
@@ -25,7 +25,7 @@ fun test() {
val t3 = bar(::baz)
bar(::<!UNRESOLVED_REFERENCE!>foo<!>)
bar(::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>)
}
}
}
@@ -21,5 +21,5 @@ FILE: eagerAndPostponedCallableReferences.kt
lval a4: R|B| = R|/foo|<R|B|>(::R|/multiple|, ::R|/singleB|)
lval a5: R|A| = R|/foo|<R|A|>(::R|/singleA|, ::R|/singleA|)
lval a6: R|it(A & B)| = R|/foo|<R|it(A & B)|>(::R|/singleA|, ::R|/singleB|)
R|/foo|<R|kotlin/Nothing|>(::<Unresolved reference: multiple>#, ::<Unresolved reference: multiple>#)
R|/foo|<R|kotlin/Nothing|>(::<Ambiguity: multiple, [/multiple, /multiple]>#, ::<Ambiguity: multiple, [/multiple, /multiple]>#)
}
@@ -22,5 +22,5 @@ fun test() {
val a6 = foo(::singleA, ::singleB)
foo(::<!UNRESOLVED_REFERENCE!>multiple<!>, ::<!UNRESOLVED_REFERENCE!>multiple<!>)
foo(::<!OVERLOAD_RESOLUTION_AMBIGUITY!>multiple<!>, ::<!OVERLOAD_RESOLUTION_AMBIGUITY!>multiple<!>)
}
@@ -9,12 +9,12 @@ FILE: moreSpecificAmbiguousExtensions.kt
}
public final fun test(): R|kotlin/Unit| {
lval extFun1: R|@ExtensionFunctionType kotlin/reflect/KFunction2<IA, IB, kotlin/Unit>| = Q|IA|::R|/extFun|
lval extFun2: <ERROR TYPE REF: No result type for initializer> = Q|IB|::<Unresolved reference: extFun>#
lval extFun2: R|ERROR CLASS: Ambiguity: extFun, [/extFun, /extFun]| = Q|IB|::<Ambiguity: extFun, [/extFun, /extFun]>#
}
public final fun testWithExpectedType(): R|kotlin/Unit| {
lval extFun_AB_A: R|IA.(IB) -> kotlin/Unit| = Q|IA|::R|/extFun|
lval extFun_AA_B: R|IA.(IA) -> kotlin/Unit| = Q|IB|::<Unresolved reference: extFun>#
lval extFun_BB_A: R|IB.(IB) -> kotlin/Unit| = Q|IA|::R|/extFun|
lval extFun_BA_B: R|IB.(IA) -> kotlin/Unit| = Q|IB|::R|/extFun|
lval extFun_BB_B: R|IB.(IB) -> kotlin/Unit| = Q|IB|::<Unresolved reference: extFun>#
lval extFun_BB_B: R|IB.(IB) -> kotlin/Unit| = Q|IB|::<Ambiguity: extFun, [/extFun, /extFun]>#
}
@@ -6,7 +6,7 @@ fun IB.extFun(x: IA) {}
fun test() {
val extFun1 = IA::extFun
val extFun2 = IB::<!UNRESOLVED_REFERENCE!>extFun<!>
val extFun2 = IB::<!OVERLOAD_RESOLUTION_AMBIGUITY!>extFun<!>
}
fun testWithExpectedType() {
@@ -15,5 +15,5 @@ fun testWithExpectedType() {
val extFun_AA_B: IA.(IA) -> Unit = IB::<!UNRESOLVED_REFERENCE!>extFun<!>
val extFun_BB_A: IB.(IB) -> Unit = IA::extFun
val extFun_BA_B: IB.(IA) -> Unit = IB::extFun
val extFun_BB_B: IB.(IB) -> Unit = IB::<!UNRESOLVED_REFERENCE!>extFun<!>
val extFun_BB_B: IB.(IB) -> Unit = IB::<!OVERLOAD_RESOLUTION_AMBIGUITY!>extFun<!>
}
@@ -10,5 +10,5 @@ FILE: manyInnermanyOuterCandidatesAmbiguity.kt
^bar Int(1)
}
public final fun main(): R|kotlin/Unit| {
<Ambiguity: foo, [/foo, /foo]>#(::<Unresolved reference: bar>#)
<Ambiguity: foo, [/foo, /foo]>#(::<Ambiguity: bar, [/bar, /bar]>#)
}
@@ -6,5 +6,5 @@ fun bar(): Int = 1
fun bar(x: String): Int = 1
fun main() {
<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(::<!UNRESOLVED_REFERENCE!>bar<!>)
<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(::<!OVERLOAD_RESOLUTION_AMBIGUITY!>bar<!>)
}