[FIR] Report INAPPLICABLE_CANDIDATE or more specific diagnostic for callable references

... instead of just UNRESOLVED_REFERENCE when something went wrong
during resolution.

#KT-59401 related
This commit is contained in:
Kirill Rakhman
2023-11-03 13:39:27 +01:00
committed by Space Team
parent 6b7eeec181
commit d91000e39c
44 changed files with 80 additions and 78 deletions
@@ -53,7 +53,7 @@ FILE: main.kt
R|/foo1|(Q|KotlinClass|::R|/KotlinClass.Companion.baz|) R|/foo1|(Q|KotlinClass|::R|/KotlinClass.Companion.baz|)
R|/foo2|(Q|KotlinClass|::R|/KotlinClass.baz|) R|/foo2|(Q|KotlinClass|::R|/KotlinClass.baz|)
<Ambiguity: foo3, [/foo3, /foo3]>#(Q|KotlinClass|::R|/KotlinClass.baz|) <Ambiguity: foo3, [/foo3, /foo3]>#(Q|KotlinClass|::R|/KotlinClass.baz|)
R|/foo1<Inapplicable(INAPPLICABLE): /foo1>#|(Q|KotlinClass|::<Unresolved reference: bar>#) R|/foo1<Inapplicable(INAPPLICABLE): /foo1>#|(Q|KotlinClass|::<Inapplicable(INAPPLICABLE): /JavaClass.bar>#)
R|/foo2|(Q|KotlinClass|::R|/JavaClass.bar|) R|/foo2|(Q|KotlinClass|::R|/JavaClass.bar|)
R|/foo3|(Q|KotlinClass|::R|/JavaClass.bar|) R|/foo3|(Q|KotlinClass|::R|/JavaClass.bar|)
R|/foo1|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|) R|/foo1|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|)
@@ -34,7 +34,7 @@ fun main() {
<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo3<!>(KotlinClass::baz) <!OVERLOAD_RESOLUTION_AMBIGUITY!>foo3<!>(KotlinClass::baz)
// Type mismatch // Type mismatch
foo1(KotlinClass::<!UNRESOLVED_REFERENCE!>bar<!>) foo1(KotlinClass::<!INAPPLICABLE_CANDIDATE!>bar<!>)
foo2(KotlinClass::bar) foo2(KotlinClass::bar)
foo3(KotlinClass::bar) foo3(KotlinClass::bar)
@@ -10,6 +10,6 @@ FILE: resolveCallableReferencesAfterAllSimpleArguments.kt
public final fun <T> baz(e: R|T|, f: R|(T) -> kotlin/Unit|): R|kotlin/Unit| { public final fun <T> baz(e: R|T|, f: R|(T) -> kotlin/Unit|): R|kotlin/Unit| {
} }
public final fun test(a: R|A|, b: R|B|): R|kotlin/Unit| { public final fun test(a: R|A|, b: R|B|): R|kotlin/Unit| {
R|/baz<Inapplicable(INAPPLICABLE): /baz>#|<R|A|>(R|<local>/a|, ::<Unresolved reference: fooB>#) R|/baz<Inapplicable(INAPPLICABLE): /baz>#|<R|A|>(R|<local>/a|, ::<Inapplicable(INAPPLICABLE): /fooB>#)
R|/bar<Inapplicable(INAPPLICABLE): /bar>#|<R|A|>(::<Unresolved reference: fooB>#, R|<local>/a|) R|/bar<Inapplicable(INAPPLICABLE): /bar>#|<R|A|>(::<Inapplicable(INAPPLICABLE): /fooB>#, R|<local>/a|)
} }
@@ -7,6 +7,6 @@ fun <T> bar(f: (T) -> Unit, e: T) {}
fun <T> baz(e: T, f: (T) -> Unit) {} fun <T> baz(e: T, f: (T) -> Unit) {}
fun test(a: A, b: B) { fun test(a: A, b: B) {
baz(a, ::<!UNRESOLVED_REFERENCE!>fooB<!>) baz(a, ::<!INAPPLICABLE_CANDIDATE!>fooB<!>)
bar(::<!UNRESOLVED_REFERENCE!>fooB<!>, a) bar(::<!INAPPLICABLE_CANDIDATE!>fooB<!>, a)
} }
@@ -9,7 +9,7 @@ FILE: implicitTypes.kt
^bar Int(1) ^bar Int(1)
} }
public final fun loop1(): R|(ERROR CLASS: Cannot infer argument for type parameter T) -> ERROR CLASS: Cannot infer argument for type parameter R| { public final fun loop1(): R|(ERROR CLASS: Cannot infer argument for type parameter T) -> ERROR CLASS: Cannot infer argument for type parameter R| {
^loop1 R|/use<Inapplicable(INAPPLICABLE): /use>#|<<ERROR TYPE REF: Cannot infer argument for type parameter T>, <ERROR TYPE REF: Cannot infer argument for type parameter R>>(::<Unresolved reference: loop2>#) ^loop1 R|/use<Inapplicable(INAPPLICABLE): /use>#|<<ERROR TYPE REF: Cannot infer argument for type parameter T>, <ERROR TYPE REF: Cannot infer argument for type parameter R>>(::<Inapplicable(INAPPLICABLE): /loop2>#)
} }
public final fun loop2(): <ERROR TYPE REF: cycle> { public final fun loop2(): <ERROR TYPE REF: cycle> {
^loop2 R|/loop1|() ^loop2 R|/loop1|()
@@ -3,5 +3,5 @@ fun <T, R> use(x: (T) -> R): (T) -> R = x
fun foo() = use(::bar) fun foo() = use(::bar)
fun bar(x: String) = 1 fun bar(x: String) = 1
fun loop1() = use(::<!UNRESOLVED_REFERENCE!>loop2<!>) fun loop1() = use(::<!INAPPLICABLE_CANDIDATE!>loop2<!>)
fun loop2() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>loop1()<!> fun loop2() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>loop1()<!>
@@ -9,7 +9,7 @@ FILE: implicitTypes.reversed.kt
^bar Int(1) ^bar Int(1)
} }
public final fun loop1(): R|(ERROR CLASS: Cannot infer argument for type parameter T) -> ERROR CLASS: Cannot infer argument for type parameter R| { public final fun loop1(): R|(ERROR CLASS: Cannot infer argument for type parameter T) -> ERROR CLASS: Cannot infer argument for type parameter R| {
^loop1 R|/use<Inapplicable(INAPPLICABLE): /use>#|<<ERROR TYPE REF: Cannot infer argument for type parameter T>, <ERROR TYPE REF: Cannot infer argument for type parameter R>>(::<Unresolved reference: loop2>#) ^loop1 R|/use<Inapplicable(INAPPLICABLE): /use>#|<<ERROR TYPE REF: Cannot infer argument for type parameter T>, <ERROR TYPE REF: Cannot infer argument for type parameter R>>(::<Inapplicable(INAPPLICABLE): /loop2>#)
} }
public final fun loop2(): R|(ERROR CLASS: Cannot infer argument for type parameter T) -> ERROR CLASS: Cannot infer argument for type parameter R| { public final fun loop2(): R|(ERROR CLASS: Cannot infer argument for type parameter T) -> ERROR CLASS: Cannot infer argument for type parameter R| {
^loop2 R|/loop1|() ^loop2 R|/loop1|()
@@ -3,5 +3,5 @@ fun <T, R> use(x: (T) -> R): (T) -> R = x
fun foo() = use(::bar) fun foo() = use(::bar)
fun bar(x: String) = 1 fun bar(x: String) = 1
fun loop1() = use(::<!UNRESOLVED_REFERENCE!>loop2<!>) fun loop1() = use(::<!INAPPLICABLE_CANDIDATE!>loop2<!>)
fun loop2() = loop1() fun loop2() = loop1()
@@ -414,11 +414,13 @@ class FirCallResolver(
!isSuccess -> { !isSuccess -> {
val errorReference = buildReferenceWithErrorCandidate( val errorReference = buildReferenceWithErrorCandidate(
info, info,
if (applicability == CandidateApplicability.K2_UNSUPPORTED) { when {
val unsupportedResolutionDiagnostic = reducedCandidates.firstOrNull()?.diagnostics?.firstOrNull() as? Unsupported applicability == CandidateApplicability.K2_UNSUPPORTED -> {
ConeUnsupported(unsupportedResolutionDiagnostic?.message ?: "", unsupportedResolutionDiagnostic?.source) val unsupportedResolutionDiagnostic = reducedCandidates.firstOrNull()?.diagnostics?.firstOrNull() as? Unsupported
} else { ConeUnsupported(unsupportedResolutionDiagnostic?.message ?: "", unsupportedResolutionDiagnostic?.source)
ConeUnresolvedReferenceError(info.name) }
reducedCandidates.size == 1 -> createConeDiagnosticForCandidateWithError(applicability, reducedCandidates.single())
else -> ConeUnresolvedReferenceError(info.name)
}, },
callableReferenceAccess.source callableReferenceAccess.source
) )
@@ -3,7 +3,7 @@
fun f1(x: String) {} fun f1(x: String) {}
fun f2(f: () -> Unit) {} fun f2(f: () -> Unit) {}
fun test1() = f2(::<!UNRESOLVED_REFERENCE("f1")!>f1<!>) fun test1() = f2(::<!INAPPLICABLE_CANDIDATE("fun f1(x: String): Unit")!>f1<!>)
@Target(AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.TYPE) @Target(AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.TYPE)
@@ -3,12 +3,12 @@ fun foo(x: String = "O"): String = x
fun bar(x: String = "K"): String = x fun bar(x: String = "K"): String = x
fun dump(dumpStrategy: String) { fun dump(dumpStrategy: String) {
val k0: kotlin.reflect.KFunction0<String> = returnAdapter(::<!UNRESOLVED_REFERENCE!>foo<!>) // Error: ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE val k0: kotlin.reflect.KFunction0<String> = returnAdapter(::<!INAPPLICABLE_CANDIDATE!>foo<!>) // Error: ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE
val k1: kotlin.reflect.KFunction0<String> = <!INITIALIZER_TYPE_MISMATCH!>::foo<!> val k1: kotlin.reflect.KFunction0<String> = <!INITIALIZER_TYPE_MISMATCH!>::foo<!>
// Should be error here, too // Should be error here, too
val k2: kotlin.reflect.KFunction0<String> = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>if (dumpStrategy == "KotlinLike") ::foo else ::bar<!> val k2: kotlin.reflect.KFunction0<String> = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>if (dumpStrategy == "KotlinLike") ::foo else ::bar<!>
val f0: Function0<String> = returnAdapter(::<!UNRESOLVED_REFERENCE!>foo<!>) val f0: Function0<String> = returnAdapter(::<!INAPPLICABLE_CANDIDATE!>foo<!>)
val f1: Function0<String> = ::foo val f1: Function0<String> = ::foo
val f2: Function0<String> = if (dumpStrategy == "KotlinLike") ::foo else ::bar val f2: Function0<String> = if (dumpStrategy == "KotlinLike") ::foo else ::bar
} }
@@ -6,10 +6,10 @@ public interface J {
// FILE: test.kt // FILE: test.kt
fun f1(x: Int?): Any = x::<!UNRESOLVED_REFERENCE!>hashCode<!> fun f1(x: Int?): Any = x::<!UNSAFE_CALL!>hashCode<!>
fun <T> f2(t: T): Any = t::<!UNRESOLVED_REFERENCE!>hashCode<!> fun <T> f2(t: T): Any = t::<!UNSAFE_CALL!>hashCode<!>
fun <S : String?> f3(s: S): Any = s::<!UNRESOLVED_REFERENCE!>hashCode<!> fun <S : String?> f3(s: S): Any = s::<!UNSAFE_CALL!>hashCode<!>
fun <U : Any> f4(u: U?): Any = u::<!UNRESOLVED_REFERENCE!>hashCode<!> fun <U : Any> f4(u: U?): Any = u::<!UNSAFE_CALL!>hashCode<!>
fun f5(c: List<*>): Any = c[0]::<!UNRESOLVED_REFERENCE!>hashCode<!> fun f5(c: List<*>): Any = c[0]::<!UNSAFE_CALL!>hashCode<!>
fun f6(j: J): Any = j.platformString()::hashCode fun f6(j: J): Any = j.platformString()::hashCode
@@ -9,7 +9,7 @@ class Foo<out T>(name: T) {
val ok2 = this@Foo::prop val ok2 = this@Foo::prop
val ok3 = object { val y: Any = this@Foo::prop } val ok3 = object { val y: Any = this@Foo::prop }
val fail1 = Foo(prop)::<!UNRESOLVED_REFERENCE!>prop<!> val fail1 = Foo(prop)::<!INVISIBLE_REFERENCE!>prop<!>
} }
fun testFunc() { fun testFunc() {
@@ -17,7 +17,7 @@ class Foo<out T>(name: T) {
val ok2 = this@Foo::func val ok2 = this@Foo::func
val ok3 = object { val y: Any = this@Foo::func } val ok3 = object { val y: Any = this@Foo::func }
val fail1 = Foo(prop)::<!UNRESOLVED_REFERENCE!>func<!> val fail1 = Foo(prop)::<!INVISIBLE_REFERENCE!>func<!>
} }
private fun func(t: T): T = t private fun func(t: T): T = t
@@ -19,9 +19,9 @@ class Test {
fun <T> List<T>.testCallable1(): () -> Unit = a::foo fun <T> List<T>.testCallable1(): () -> Unit = a::foo
fun <T> List<T>.testCallable1a(): () -> Unit = <!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>a<!><T>::foo fun <T> List<T>.testCallable1a(): () -> Unit = <!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>a<!><T>::foo
fun <T> List<T>.testCallable2(): () -> Unit = b?::<!UNRESOLVED_REFERENCE!>foo<!> fun <T> List<T>.testCallable2(): () -> Unit = b?::<!UNSAFE_CALL!>foo<!>
fun <T> List<T>.testCallable3(): () -> Unit = <!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>b<!><T, Any>::<!UNRESOLVED_REFERENCE!>foo<!> fun <T> List<T>.testCallable3(): () -> Unit = <!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>b<!><T, Any>::<!UNSAFE_CALL!>foo<!>
fun <T> List<T>.testCallable4(): () -> Unit = <!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>b<!><T>?::<!UNRESOLVED_REFERENCE!>foo<!> fun <T> List<T>.testCallable4(): () -> Unit = <!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>b<!><T>?::<!UNSAFE_CALL!>foo<!>
fun <T> List<T>.testClassLiteral1() = a::class fun <T> List<T>.testClassLiteral1() = a::class
fun <T> List<T>.testClassLiteral1a() = <!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>a<!><T>::class fun <T> List<T>.testClassLiteral1a() = <!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>a<!><T>::class
@@ -4,4 +4,4 @@ package test
fun nullableFun(): Int? = null fun nullableFun(): Int? = null
fun Int.foo() {} fun Int.foo() {}
val test1 = nullableFun()?::<!UNRESOLVED_REFERENCE!>foo<!> val test1 = nullableFun()?::<!UNSAFE_CALL!>foo<!>
@@ -18,6 +18,6 @@ fun <K, V> B<K>.star(p: KProperty1<*, V>): B<V> = TODO()
fun <R : A> B<R>.test(){ fun <R : A> B<R>.test(){
foo(A::bla) foo(A::bla)
bar(A::bla) bar(A::bla)
baz(A::<!UNRESOLVED_REFERENCE!>bla<!>) baz(A::<!INAPPLICABLE_CANDIDATE!>bla<!>)
star(A::bla) star(A::bla)
} }
@@ -14,5 +14,5 @@ fun <K, V> B<K>.foo(p: KProperty1<K, V>) {}
class C : A class C : A
fun <R : A> B<R>.test(){ fun <R : A> B<R>.test(){
foo(C::<!UNRESOLVED_REFERENCE!>bla<!>) foo(C::<!INAPPLICABLE_CANDIDATE!>bla<!>)
} }
@@ -7,6 +7,6 @@ fun <T> takeIt(x: T, f: SubFunction) {}
fun cr() {} fun cr() {}
fun test() { fun test() {
takeIt(42, ::<!UNRESOLVED_REFERENCE!>cr<!>) takeIt(42, ::<!INAPPLICABLE_CANDIDATE!>cr<!>)
takeIt(42, <!ARGUMENT_TYPE_MISMATCH!>{ }<!>) takeIt(42, <!ARGUMENT_TYPE_MISMATCH!>{ }<!>)
} }
@@ -8,5 +8,5 @@ fun main() {
::<!UNRESOLVED_REFERENCE!>A<!> ::<!UNRESOLVED_REFERENCE!>A<!>
::<!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>B<!> ::<!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>B<!>
::<!CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR!>C<!> // KT-3465 ::<!CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR!>C<!> // KT-3465
::<!UNRESOLVED_REFERENCE!>D<!> ::<!INVISIBLE_REFERENCE!>D<!>
} }
@@ -25,7 +25,7 @@ class A {
expectFunction0Unit(::foo) expectFunction0Unit(::foo)
expectFunction0String(::foo) expectFunction0String(::foo)
expectFunction1Unit(::<!UNRESOLVED_REFERENCE!>foo<!>) expectFunction1Unit(::<!INAPPLICABLE_CANDIDATE!>foo<!>)
expectFunction1String(::<!UNRESOLVED_REFERENCE!>foo<!>) expectFunction1String(::<!INAPPLICABLE_CANDIDATE!>foo<!>)
} }
} }
@@ -16,14 +16,14 @@ fun <T> bar(s: T) {}
fun <T> complex(t: T, f: (T) -> Unit) {} fun <T> complex(t: T, f: (T) -> Unit) {}
fun test1() { fun test1() {
foo(1, A::<!UNRESOLVED_REFERENCE!>invokeLater<!>) // KT-24507 SAM conversion accidentally applied to callable reference and incorrectly handled via BE foo(1, A::<!INAPPLICABLE_CANDIDATE!>invokeLater<!>) // KT-24507 SAM conversion accidentally applied to callable reference and incorrectly handled via BE
foo(1, ::bar) foo(1, ::bar)
complex(1, ::bar) complex(1, ::bar)
} }
fun <R> test2(x: R) { fun <R> test2(x: R) {
foo(x, A::<!UNRESOLVED_REFERENCE!>invokeLater<!>) // KT-24507 SAM conversion accidentally applied to callable reference and incorrectly handled via BE foo(x, A::<!INAPPLICABLE_CANDIDATE!>invokeLater<!>) // KT-24507 SAM conversion accidentally applied to callable reference and incorrectly handled via BE
foo(x, ::bar) foo(x, ::bar)
complex(x, ::bar) complex(x, ::bar)
@@ -13,7 +13,7 @@ fun <T> Wrapper<T>.baz(transform: (T) -> Unit): T = TODO()
fun test() { fun test() {
takeFun<String>(::foo) takeFun<String>(::foo)
takeFun<String>(::<!UNRESOLVED_REFERENCE!>fooInt<!>) takeFun<String>(::<!INAPPLICABLE_CANDIDATE!>fooInt<!>)
callFun<String, Wrapper<String>>(::createWrapper) callFun<String, Wrapper<String>>(::createWrapper)
callFun<Int, Wrapper<Number>>(::createWrapper) callFun<Int, Wrapper<Number>>(::createWrapper)
@@ -22,8 +22,8 @@ fun test1() {
fun <T> test2() { fun <T> test2() {
bar<Wrapper, Int, String>(Wrapper::fooReturnString).checkType { _<Tripple<Wrapper, Int, String>>() } bar<Wrapper, Int, String>(Wrapper::fooReturnString).checkType { _<Tripple<Wrapper, Int, String>>() }
bar<Wrapper, T, String>(Wrapper::fooReturnString).checkType { _<Tripple<Wrapper, T, String>>() } bar<Wrapper, T, String>(Wrapper::fooReturnString).checkType { _<Tripple<Wrapper, T, String>>() }
bar<Wrapper, T, T>(Wrapper::<!UNRESOLVED_REFERENCE!>fooReturnString<!>) bar<Wrapper, T, T>(Wrapper::<!INAPPLICABLE_CANDIDATE!>fooReturnString<!>)
bar<Wrapper, Int, Int>(Wrapper::<!UNRESOLVED_REFERENCE!>fooReturnString<!>) bar<Wrapper, Int, Int>(Wrapper::<!INAPPLICABLE_CANDIDATE!>fooReturnString<!>)
bar<Wrapper, Int, T>(Wrapper::fooTakeInt).checkType { _<Tripple<Wrapper, Int, T>>() } bar<Wrapper, Int, T>(Wrapper::fooTakeInt).checkType { _<Tripple<Wrapper, Int, T>>() }
bar<Wrapper, Int, String>(Wrapper::fooTakeInt).checkType { _<Tripple<Wrapper, Int, String>>() } bar<Wrapper, Int, String>(Wrapper::fooTakeInt).checkType { _<Tripple<Wrapper, Int, String>>() }
@@ -4,7 +4,7 @@ fun foo(vararg ints: Int) {}
fun test(i: IntArray) { fun test(i: IntArray) {
myLet(i, ::foo) myLet(i, ::foo)
myLet(::foo) myLet(::foo)
myLet<Int>(::<!UNRESOLVED_REFERENCE!>foo<!>) myLet<Int>(::<!INAPPLICABLE_CANDIDATE!>foo<!>)
myLet<IntArray>(::foo) myLet<IntArray>(::foo)
myLetExplicit1(::foo) myLetExplicit1(::foo)
myLetExplicit2(::foo) myLetExplicit2(::foo)
@@ -1,5 +1,5 @@
fun box(): String { fun box(): String {
if (true) X::<!UNRESOLVED_REFERENCE!>y<!> else null if (true) X::<!INVISIBLE_REFERENCE!>y<!> else null
return "OK" return "OK"
} }
@@ -15,11 +15,11 @@ class A {
fun test() { fun test() {
String::<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>ext<!> String::<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>ext<!>
Obj::<!UNRESOLVED_REFERENCE!>ext<!> <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>Obj::ext<!>
String::<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>ext2<!> String::<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>ext2<!>
A.Companion::<!UNRESOLVED_REFERENCE!>ext2<!> <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>A.Companion::ext2<!>
A::<!UNRESOLVED_REFERENCE!>ext2<!> <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>A::ext2<!>
A::<!UNRESOLVED_REFERENCE!>foo<!> A::<!UNRESOLVED_REFERENCE!>foo<!>
A::<!UNRESOLVED_REFERENCE!>bar<!> A::<!UNRESOLVED_REFERENCE!>bar<!>
@@ -21,6 +21,6 @@ fun test() {
val pubMutRef: KMutableProperty1<JavaClass, Long> = JavaClass::publicMutable val pubMutRef: KMutableProperty1<JavaClass, Long> = JavaClass::publicMutable
val protFinRef: KProperty1<JavaClass, Double> = JavaClass::protectedFinal val protFinRef: KProperty1<JavaClass, Double> = JavaClass::protectedFinal
val protMutRef: KMutableProperty1<JavaClass, Char> = JavaClass::protectedMutable val protMutRef: KMutableProperty1<JavaClass, Char> = JavaClass::protectedMutable
val privFinRef: KProperty1<JavaClass, String?> = JavaClass::<!UNRESOLVED_REFERENCE!>privateFinal<!> val privFinRef: KProperty1<JavaClass, String?> = JavaClass::<!INVISIBLE_REFERENCE!>privateFinal<!>
val privMutRef: KMutableProperty1<JavaClass, Any?> = JavaClass::<!UNRESOLVED_REFERENCE!>privateMutable<!> val privMutRef: KMutableProperty1<JavaClass, Any?> = JavaClass::<!INVISIBLE_REFERENCE!>privateMutable<!>
} }
@@ -23,6 +23,6 @@ fun test() {
val pubMutRef: KMutableProperty0<Any?> = ::publicMutable val pubMutRef: KMutableProperty0<Any?> = ::publicMutable
val protFinRef: KProperty<Double> = ::protectedFinal val protFinRef: KProperty<Double> = ::protectedFinal
val protMutRef: KMutableProperty<Char> = ::protectedMutable val protMutRef: KMutableProperty<Char> = ::protectedMutable
val privFinRef: KProperty<JavaClass?> = ::<!UNRESOLVED_REFERENCE!>privateFinal<!> val privFinRef: KProperty<JavaClass?> = ::<!INVISIBLE_REFERENCE!>privateFinal<!>
val privMutRef: KMutableProperty<Throwable?> = ::<!UNRESOLVED_REFERENCE!>privateMutable<!> val privMutRef: KMutableProperty<Throwable?> = ::<!INVISIBLE_REFERENCE!>privateMutable<!>
} }
@@ -22,6 +22,6 @@ object Local {
fun baz(x: Int, y: Int = 0): Int = 0 fun baz(x: Int, y: Int = 0): Int = 0
fun test() { fun test() {
bar(::<!UNRESOLVED_REFERENCE!>baz<!>) bar(::<!INAPPLICABLE_CANDIDATE!>baz<!>)
} }
} }
@@ -22,6 +22,6 @@ object Local {
fun baz(x: Int, y: Int = 0): Int = 0 fun baz(x: Int, y: Int = 0): Int = 0
fun test() { fun test() {
bar(::<!UNRESOLVED_REFERENCE!>baz<!>) bar(::<!INAPPLICABLE_CANDIDATE!>baz<!>)
} }
} }
@@ -5,4 +5,4 @@ import kotlin.reflect.KProperty0
object A object A
fun <TProperty> property0(property: KProperty0<TProperty>) = A fun <TProperty> property0(property: KProperty0<TProperty>) = A
val <K> K.key get() : A = property0(Map.Entry<K, *>::<!UNRESOLVED_REFERENCE!>key<!>) // should be forbidden val <K> K.key get() : A = property0(Map.Entry<K, *>::<!INAPPLICABLE_CANDIDATE!>key<!>) // should be forbidden
@@ -10,6 +10,6 @@ fun <T> baz(e: T, f: (T) -> Unit) {}
fun test(a: A, b: B) { fun test(a: A, b: B) {
// Note that diagnostic is always on callable references as they are resolved after simple arguments // Note that diagnostic is always on callable references as they are resolved after simple arguments
baz(a, ::<!UNRESOLVED_REFERENCE!>fooB<!>) baz(a, ::<!INAPPLICABLE_CANDIDATE!>fooB<!>)
bar(::<!UNRESOLVED_REFERENCE!>fooB<!>, a) bar(::<!INAPPLICABLE_CANDIDATE!>fooB<!>, a)
} }
@@ -26,7 +26,7 @@ infix fun filter(filter: (R, Any?) -> Boolean): Delegate<R, T>
class GitLabChangesProcessor: DatabaseEntity { class GitLabChangesProcessor: DatabaseEntity {
var buildProcessors by child_many( var buildProcessors by child_many(
GitLabBuildProcessor::class.java, GitLabBuildProcessor::class.java,
GitLabBuildProcessor::<!UNRESOLVED_REFERENCE!>processor<!> GitLabBuildProcessor::<!INAPPLICABLE_CANDIDATE!>processor<!>
) )
} }
@@ -27,7 +27,7 @@ infix fun filter(filter: (R, Any?) -> Boolean): Delegate<R, T>
class GitLabChangesProcessor: DatabaseEntity { class GitLabChangesProcessor: DatabaseEntity {
var buildProcessors by child_many( var buildProcessors by child_many(
GitLabBuildProcessor::class.java, GitLabBuildProcessor::class.java,
GitLabBuildProcessor::<!UNRESOLVED_REFERENCE!>processor<!> GitLabBuildProcessor::<!INAPPLICABLE_CANDIDATE!>processor<!>
) )
} }
@@ -56,7 +56,7 @@ class Derived : Intermediate() {
fun bar() = a // Non-reference fun bar() = a // Non-reference
fun baz() = this::<!UNRESOLVED_REFERENCE!>b<!> // Non-protected fun baz() = this::<!INVISIBLE_REFERENCE!>b<!> // Non-protected
} }
typealias Alias = Intermediate typealias Alias = Intermediate
@@ -90,5 +90,5 @@ class DirectlyDerived : BaseJava() {
} }
fun test(d: Derived) { fun test(d: Derived) {
d::<!UNRESOLVED_REFERENCE!>a<!> // Field is also invisible d::<!INVISIBLE_REFERENCE!>a<!> // Field is also invisible
} }
@@ -114,14 +114,14 @@ fun <T : Foo, R: Number, D: Int> main() {
bar7(Foo::resolve) // OK bar7(Foo::resolve) // OK
// with LHS and sentension function expected type // with LHS and sentension function expected type
bar10<D>(Int::<!UNRESOLVED_REFERENCE!>x1<!>) // ERROR before the fix in NI bar10<D>(Int::<!INAPPLICABLE_CANDIDATE!>x1<!>) // ERROR before the fix in NI
bar10<Int>(Int::x1) // OK bar10<Int>(Int::x1) // OK
bar10(Int::x1) // OK bar10(Int::x1) // OK
fun Int.ext() { fun Int.ext() {
// with LHS and sentension function expected type // with LHS and sentension function expected type
bar10<D>(::<!UNRESOLVED_REFERENCE!>x1<!>) // ERROR before the fix in NI bar10<D>(::<!INAPPLICABLE_CANDIDATE!>x1<!>) // ERROR before the fix in NI
bar10<Int>(::<!UNRESOLVED_REFERENCE!>x1<!>) // OK bar10<Int>(::<!INAPPLICABLE_CANDIDATE!>x1<!>) // OK
bar10(::<!UNRESOLVED_REFERENCE!>x1<!>) // OK bar10(::<!INAPPLICABLE_CANDIDATE!>x1<!>) // OK
} }
} }
@@ -18,7 +18,7 @@ public class Inv<T> {
fun test(inv: Inv<String>) { fun test(inv: Inv<String>) {
val m: ((String) -> String) -> Inv<String> = <!INITIALIZER_TYPE_MISMATCH!>inv::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>map<!><!> val m: ((String) -> String) -> Inv<String> = <!INITIALIZER_TYPE_MISMATCH!>inv::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>map<!><!>
take(inv::<!UNRESOLVED_REFERENCE!>map<!>) take(inv::<!INAPPLICABLE_CANDIDATE!>map<!>)
} }
fun take(f: ((String) -> String) -> Inv<String>) {} fun take(f: ((String) -> String) -> Inv<String>) {}
@@ -14,5 +14,5 @@ fun test() {
foo2(42, ::bar2) foo2(42, ::bar2)
foo2("str", ::bar2) foo2("str", ::bar2)
foo2(42, ::<!UNRESOLVED_REFERENCE!>bar1<!>) foo2(42, ::<!INAPPLICABLE_CANDIDATE!>bar1<!>)
} }
@@ -20,9 +20,9 @@ fun test() {
useStringArray(::stringVararg) useStringArray(::stringVararg)
useIntArray(::numberVararg) useIntArray(::numberVararg)
usePrimitiveIntArray(::intVararg) usePrimitiveIntArray(::intVararg)
useIntArray(::<!UNRESOLVED_REFERENCE!>intVararg<!>) useIntArray(::<!INAPPLICABLE_CANDIDATE!>intVararg<!>)
useMixedStringArgs1(::<!UNRESOLVED_REFERENCE!>stringVararg<!>) useMixedStringArgs1(::<!INAPPLICABLE_CANDIDATE!>stringVararg<!>)
useMixedStringArgs2(::<!UNRESOLVED_REFERENCE!>stringVararg<!>) useMixedStringArgs2(::<!INAPPLICABLE_CANDIDATE!>stringVararg<!>)
useMixedStringArgs3(::<!UNRESOLVED_REFERENCE!>stringVararg<!>) useMixedStringArgs3(::<!INAPPLICABLE_CANDIDATE!>stringVararg<!>)
useTwoStringArrays(::<!UNRESOLVED_REFERENCE!>stringVararg<!>) useTwoStringArrays(::<!INAPPLICABLE_CANDIDATE!>stringVararg<!>)
} }
@@ -10,7 +10,7 @@ suspend fun String.id(): String = this
fun box() { fun box() {
val x = "f" val x = "f"
builder { builder {
go1(x::<!UNRESOLVED_REFERENCE!>id<!>) go1(x::<!INAPPLICABLE_CANDIDATE!>id<!>)
go2(x::<!UNRESOLVED_REFERENCE!>id<!>) go2(x::<!INAPPLICABLE_CANDIDATE!>id<!>)
} }
} }
@@ -14,8 +14,8 @@ suspend fun bar(x: Int) {}
fun test() { fun test() {
test0(::foo) test0(::foo)
test1(::<!UNRESOLVED_REFERENCE!>foo<!>) test1(::<!INAPPLICABLE_CANDIDATE!>foo<!>)
test0(::<!UNRESOLVED_REFERENCE!>bar<!>) test0(::<!INAPPLICABLE_CANDIDATE!>bar<!>)
test1(::bar) test1(::bar)
} }
@@ -9,7 +9,7 @@ class ProcessorWithParent : Entity {
} }
class ProcessorWithChildren : Entity { class ProcessorWithChildren : Entity {
var processors by children(ProcessorWithParent::class.java, ProcessorWithParent::<!UNRESOLVED_REFERENCE!>processor<!>) var processors by children(ProcessorWithParent::class.java, ProcessorWithParent::<!INAPPLICABLE_CANDIDATE!>processor<!>)
} }
class Processor2WithParent : Entity { class Processor2WithParent : Entity {
@@ -18,7 +18,7 @@ FILE: kt50994.fir.kt
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
public final var processors: R|kotlin/collections/MutableCollection<ProcessorWithParent>|by this@R|/ProcessorWithChildren|.R|/children<Inapplicable(INAPPLICABLE): /children>#|<R|ProcessorWithChildren|, R|ProcessorWithParent|>(<getClass>(Q|ProcessorWithParent|).R|kotlin/jvm/java|<R|ProcessorWithParent|>, Q|ProcessorWithParent|::<Unresolved reference: processor>#) public final var processors: R|kotlin/collections/MutableCollection<ProcessorWithParent>|by this@R|/ProcessorWithChildren|.R|/children<Inapplicable(INAPPLICABLE): /children>#|<R|ProcessorWithChildren|, R|ProcessorWithParent|>(<getClass>(Q|ProcessorWithParent|).R|kotlin/jvm/java|<R|ProcessorWithParent|>, Q|ProcessorWithParent|::<Inapplicable(INAPPLICABLE): /ProcessorWithParent.processor>#)
public get(): R|kotlin/collections/MutableCollection<ProcessorWithParent>| { public get(): R|kotlin/collections/MutableCollection<ProcessorWithParent>| {
^ this@R|/ProcessorWithChildren|.D|/ProcessorWithChildren.processors|.R|SubstitutionOverride</Delegate.getValue: R|kotlin/collections/MutableCollection<ProcessorWithParent>|>|(this@R|/ProcessorWithChildren|, ::R|/ProcessorWithChildren.processors|) ^ this@R|/ProcessorWithChildren|.D|/ProcessorWithChildren.processors|.R|SubstitutionOverride</Delegate.getValue: R|kotlin/collections/MutableCollection<ProcessorWithParent>|>|(this@R|/ProcessorWithChildren|, ::R|/ProcessorWithChildren.processors|)
} }
@@ -21,7 +21,7 @@ fun case1() {
val x : Case1? = Case1() val x : Case1? = Case1()
x.<!VAL_REASSIGNMENT!>x<!> = "0" x.<!VAL_REASSIGNMENT!>x<!> = "0"
x?.<!VAL_REASSIGNMENT!>x<!> = "0" x?.<!VAL_REASSIGNMENT!>x<!> = "0"
<!VARIABLE_EXPECTED!>x::<!UNRESOLVED_REFERENCE!>x<!><!> = TODO() <!VARIABLE_EXPECTED!>x::x<!> = TODO()
} }
class Case1{ class Case1{
@@ -37,7 +37,7 @@ fun case2() {
val x : Case2? = Case2(null) val x : Case2? = Case2(null)
x.<!VAL_REASSIGNMENT!>x<!> = "0" x.<!VAL_REASSIGNMENT!>x<!> = "0"
x?.<!VAL_REASSIGNMENT!>x<!> = "0" x?.<!VAL_REASSIGNMENT!>x<!> = "0"
<!VARIABLE_EXPECTED!>x::<!UNRESOLVED_REFERENCE!>x<!><!> = TODO() <!VARIABLE_EXPECTED!>x::x<!> = TODO()
} }
class Case2(val x: Any?) {} class Case2(val x: Any?) {}
@@ -50,7 +50,7 @@ fun case3() {
val x : Case3? = Case3() val x : Case3? = Case3()
x.<!VAL_REASSIGNMENT!>x<!> = "0" x.<!VAL_REASSIGNMENT!>x<!> = "0"
x?.<!VAL_REASSIGNMENT!>x<!> = "0" x?.<!VAL_REASSIGNMENT!>x<!> = "0"
<!VARIABLE_EXPECTED!>x::<!UNRESOLVED_REFERENCE!>x<!><!> = TODO() <!VARIABLE_EXPECTED!>x::x<!> = TODO()
} }
class Case3() { class Case3() {