K1: add diagnostic BUILDER_INFERENCE_STUB_RECEIVER
It's reported on receivers in extension function calls with stub type, as such calls can shadow members of finalized stub types causing change of resolve when corresponding type argument specified explicitly It works by checking extension receiver during call resolution parts run That way we can easily detect if we found an extension applicable to stub receiver and report call diagnostic for it KT-53739
This commit is contained in:
committed by
teamcity
parent
105358dcf6
commit
154e53c701
+1
-1
@@ -12,7 +12,7 @@ fun main() {
|
||||
|
||||
buildList {
|
||||
add(Bar())
|
||||
this.get(0).test() // resolved to Any?.test
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>this.get(0)<!>.test() // resolved to Any?.test
|
||||
}
|
||||
buildList<Bar> {
|
||||
add(Bar())
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// WITH_STDLIB
|
||||
// SKIP_TXT
|
||||
fun test() {
|
||||
foo(
|
||||
flow { emit(0) }
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
fun test() {
|
||||
foo(
|
||||
flow { emit(0) }
|
||||
) <!BUILDER_INFERENCE_MULTI_LAMBDA_RESTRICTION!>{ it.collect <!TOO_MANY_ARGUMENTS!>{}<!> }<!>
|
||||
) <!BUILDER_INFERENCE_MULTI_LAMBDA_RESTRICTION!>{ <!BUILDER_INFERENCE_STUB_RECEIVER!>it<!>.collect <!TOO_MANY_ARGUMENTS!>{}<!> }<!>
|
||||
|
||||
// 0. Initial
|
||||
// W <: Any / declared upper bound
|
||||
|
||||
+30
-30
@@ -20,9 +20,9 @@ fun test() {
|
||||
val ret1 = build {
|
||||
emit(1)
|
||||
emit(null)
|
||||
get()?.test()
|
||||
get()?.test2()
|
||||
get().test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>.test2()
|
||||
get()?.hashCode()
|
||||
get()?.equals(1)
|
||||
// there is `String?.equals` extension
|
||||
@@ -31,9 +31,9 @@ fun test() {
|
||||
val ret2 = build {
|
||||
emit(1)
|
||||
emit(null)
|
||||
get()?.test()
|
||||
get()?.test2()
|
||||
get().test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>.test2()
|
||||
get()?.hashCode()
|
||||
get()?.equals(1)
|
||||
val x = get()
|
||||
@@ -44,9 +44,9 @@ fun test() {
|
||||
val ret3 = build {
|
||||
emit(1)
|
||||
emit(null)
|
||||
get()?.test()
|
||||
get()?.test2()
|
||||
get().test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>.test2()
|
||||
get()?.hashCode()
|
||||
get()?.equals(1)
|
||||
val x = get()
|
||||
@@ -62,9 +62,9 @@ fun test() {
|
||||
x.equals("")
|
||||
x.hashCode()
|
||||
x.toString()
|
||||
x.test()
|
||||
x<!UNNECESSARY_SAFE_CALL!>?.<!>test2()
|
||||
x.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!><!UNNECESSARY_SAFE_CALL!>?.<!>test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.test2()
|
||||
}
|
||||
|
||||
""
|
||||
@@ -104,7 +104,7 @@ fun test() {
|
||||
emit(null)
|
||||
val x = get()
|
||||
if (x == null) {
|
||||
<!TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
}
|
||||
|
||||
""
|
||||
@@ -144,7 +144,7 @@ fun test() {
|
||||
emit(null)
|
||||
val x = get()
|
||||
if (x === null) {
|
||||
<!TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
}
|
||||
|
||||
""
|
||||
@@ -153,16 +153,16 @@ fun test() {
|
||||
emit(1)
|
||||
emit(null)
|
||||
val x = get()
|
||||
<!TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
|
||||
""
|
||||
}
|
||||
val ret41 = build {
|
||||
emit(1)
|
||||
emit(null)
|
||||
get()?.test()
|
||||
get()?.test2()
|
||||
get().test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>.test2()
|
||||
get()?.hashCode()
|
||||
get()?.equals(1)
|
||||
val x = get()
|
||||
@@ -181,11 +181,11 @@ fun test() {
|
||||
}
|
||||
|
||||
if (x == null) {
|
||||
<!DEBUG_INFO_CONSTANT!>x<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, DEBUG_INFO_CONSTANT!>x<!>?.test2()
|
||||
}
|
||||
|
||||
if (x == null) {
|
||||
x.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.test2()
|
||||
}
|
||||
|
||||
if (x === null) {
|
||||
@@ -197,11 +197,11 @@ fun test() {
|
||||
}
|
||||
|
||||
if (x === null) {
|
||||
<!DEBUG_INFO_CONSTANT!>x<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, DEBUG_INFO_CONSTANT!>x<!>?.test2()
|
||||
}
|
||||
|
||||
if (x === null) {
|
||||
x.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.test2()
|
||||
}
|
||||
|
||||
""
|
||||
@@ -239,7 +239,7 @@ fun test() {
|
||||
emit(null)
|
||||
val x = get()
|
||||
if (x == null) {
|
||||
<!TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
}
|
||||
""
|
||||
}
|
||||
@@ -276,7 +276,7 @@ fun test() {
|
||||
emit(null)
|
||||
val x = get()
|
||||
if (x === null) {
|
||||
<!TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
}
|
||||
""
|
||||
}
|
||||
@@ -284,15 +284,15 @@ fun test() {
|
||||
emit(1)
|
||||
emit(null)
|
||||
val x = get()
|
||||
<!TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
""
|
||||
}
|
||||
val ret51 = build {
|
||||
emit(1)
|
||||
emit(null)
|
||||
get()?.test()
|
||||
get()?.test2()
|
||||
get().test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>.test2()
|
||||
get()?.hashCode()
|
||||
get()?.equals(1)
|
||||
val x = get()
|
||||
@@ -305,8 +305,8 @@ fun test() {
|
||||
if (x == null) {
|
||||
<!DEBUG_INFO_CONSTANT!>x<!>?.hashCode()
|
||||
<!DEBUG_INFO_CONSTANT!>x<!>?.equals(1)
|
||||
<!DEBUG_INFO_CONSTANT!>x<!>?.test2()
|
||||
x.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, DEBUG_INFO_CONSTANT!>x<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.test2()
|
||||
}
|
||||
|
||||
""
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
// WITH_STDLIB
|
||||
// SKIP_TXT
|
||||
|
||||
fun <R> a(lambda: List<R>.(R) -> Unit) {}
|
||||
|
||||
fun <T> T.extension() {}
|
||||
|
||||
fun use(p: Any?) {}
|
||||
|
||||
fun test1() {
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
this.get(0).extension()
|
||||
use(this.get(0)::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun test2() {
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
val v = this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
operator fun <T> T.getValue(thisRef: Any?, prop: Any?): T = this
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
val v by this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
class Box<TIn>(val t: TIn)
|
||||
|
||||
fun test4() {
|
||||
operator fun <T> T.provideDelegate(thisRef: Any?, prop: Any?): Box<T> = Box(this)
|
||||
operator fun <T> Box<T>.getValue(thisRef: Any?, prop: Any?): T = this.t
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
val v by this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun <R> b(lambda: R.(List<R>) -> Unit) {}
|
||||
|
||||
fun test5() {
|
||||
|
||||
operator fun <T> T.invoke(): T = this
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>b<!> {
|
||||
extension()
|
||||
this().extension()
|
||||
use(::extension)
|
||||
}
|
||||
}
|
||||
|
||||
val <T> T.genericLambda: T.((T) -> Unit) -> Unit get() = {}
|
||||
|
||||
fun test6() {
|
||||
b {
|
||||
extension()
|
||||
genericLambda { }
|
||||
genericLambda { it.extension() }
|
||||
use(::extension)
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
// WITH_STDLIB
|
||||
// SKIP_TXT
|
||||
|
||||
fun <R> a(lambda: List<R>.(R) -> Unit) {}
|
||||
|
||||
fun <T> T.extension() {}
|
||||
|
||||
fun use(p: Any?) {}
|
||||
|
||||
fun test1() {
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>this.get(0)<!>.extension()
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>this.get(0)<!>::extension)
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>it<!>::extension)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun test2() {
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
val v = this.get(0)
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>v<!>.extension()
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>v<!>::extension)
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>it<!>::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
operator fun <T> T.getValue(thisRef: Any?, prop: Any?): T = this
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
val v by <!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>this.get(0)<!>
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>v<!>.extension()
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>v<!>::extension)
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>it<!>::extension)
|
||||
}
|
||||
}
|
||||
|
||||
class Box<TIn>(val t: TIn)
|
||||
|
||||
fun test4() {
|
||||
operator fun <T> T.provideDelegate(thisRef: Any?, prop: Any?): Box<T> = Box(this)
|
||||
operator fun <T> Box<T>.getValue(thisRef: Any?, prop: Any?): T = this.t
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
val v by <!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>this.get(0)<!>
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>v<!>.extension()
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>v<!>::extension)
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>it<!>::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun <R> b(lambda: R.(List<R>) -> Unit) {}
|
||||
|
||||
fun test5() {
|
||||
|
||||
operator fun <T> T.invoke(): T = this
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>b<!> {
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>extension()<!>
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!><!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>this<!>()<!>.extension()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>use(::extension)<!>
|
||||
}
|
||||
}
|
||||
|
||||
val <T> T.genericLambda: T.((T) -> Unit) -> Unit get() = {}
|
||||
|
||||
fun test6() {
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>b<!> {
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>extension()<!>
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>genericLambda<!> { }
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>genericLambda<!> { <!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>it<!>.extension() }
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>use(::extension)<!>
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
// WITH_STDLIB
|
||||
// LANGUAGE: +NoBuilderInferenceWithoutAnnotationRestriction
|
||||
// SKIP_TXT
|
||||
|
||||
fun <R> a(lambda: List<R>.(R) -> Unit) {}
|
||||
|
||||
fun <T> T.extension() {}
|
||||
|
||||
fun use(p: Any?) {}
|
||||
|
||||
fun test1() {
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
this.get(0).extension()
|
||||
use(this.get(0)::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun test2() {
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
val v = this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
operator fun <T> T.getValue(thisRef: Any?, prop: Any?): T = this
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
val v by this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
class Box<TIn>(val t: TIn)
|
||||
|
||||
fun test4() {
|
||||
operator fun <T> T.provideDelegate(thisRef: Any?, prop: Any?): Box<T> = Box(this)
|
||||
operator fun <T> Box<T>.getValue(thisRef: Any?, prop: Any?): T = this.t
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
val v by this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun <R> b(lambda: R.(List<R>) -> Unit) {}
|
||||
|
||||
fun test5() {
|
||||
|
||||
operator fun <T> T.invoke(): T = this
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>b<!> {
|
||||
extension()
|
||||
this().extension()
|
||||
use(::extension)
|
||||
}
|
||||
}
|
||||
|
||||
val <T> T.genericLambda: T.((T) -> Unit) -> Unit get() = {}
|
||||
|
||||
fun test6() {
|
||||
b {
|
||||
extension()
|
||||
genericLambda { }
|
||||
genericLambda { it.extension() }
|
||||
use(::extension)
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
// WITH_STDLIB
|
||||
// LANGUAGE: +NoBuilderInferenceWithoutAnnotationRestriction
|
||||
// SKIP_TXT
|
||||
|
||||
fun <R> a(lambda: List<R>.(R) -> Unit) {}
|
||||
|
||||
fun <T> T.extension() {}
|
||||
|
||||
fun use(p: Any?) {}
|
||||
|
||||
fun test1() {
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
this.get(0).extension()
|
||||
use(this.get(0)::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun test2() {
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
val v = this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
operator fun <T> T.getValue(thisRef: Any?, prop: Any?): T = this
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
val v by this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
class Box<TIn>(val t: TIn)
|
||||
|
||||
fun test4() {
|
||||
operator fun <T> T.provideDelegate(thisRef: Any?, prop: Any?): Box<T> = Box(this)
|
||||
operator fun <T> Box<T>.getValue(thisRef: Any?, prop: Any?): T = this.t
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
val v by this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun <R> b(lambda: R.(List<R>) -> Unit) {}
|
||||
|
||||
fun test5() {
|
||||
|
||||
operator fun <T> T.invoke(): T = this
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>b<!> {
|
||||
extension()
|
||||
this().extension()
|
||||
use(::extension)
|
||||
}
|
||||
}
|
||||
|
||||
val <T> T.genericLambda: T.((T) -> Unit) -> Unit get() = {}
|
||||
|
||||
fun test6() {
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>b<!> {
|
||||
extension()
|
||||
genericLambda { }
|
||||
genericLambda { it.extension() }
|
||||
use(::extension)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user