Implementation and tests for KT-5840 and newly created KT-7204. Now a safe call provides not-null receiver state *inside* argument list. It works also for ?. chains. #KT-5840 Fixed.
On the other hand, argument states do not propagate to successor statements for a safe call. #KT-7204 Fixed. A few additional comments.
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
fun calc(x: List<String>?, y: Int?): Int {
|
||||
x?.get(y!! - 1)
|
||||
// y!! above should not provide smart cast here
|
||||
val yy: Int = <!TYPE_MISMATCH!>y<!>
|
||||
return yy + (x?.size() ?: 0)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?, /*1*/ y: kotlin.Int?): kotlin.Int
|
||||
@@ -0,0 +1,6 @@
|
||||
fun calc(x: List<String>?): Int {
|
||||
// After KT-5840 fix !! assertion should become unnecessary here
|
||||
x?.get(x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.size() - 1)
|
||||
// x?. or x!! above should not provide smart cast here
|
||||
return x<!UNSAFE_CALL!>.<!>size()
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?): kotlin.Int
|
||||
@@ -0,0 +1,6 @@
|
||||
fun calc(x: List<String>?): Int {
|
||||
// x should be non-null in arguments list, despite of a chain
|
||||
x?.subList(0, 1)?.get(<!DEBUG_INFO_SMARTCAST!>x<!>.size())
|
||||
// But not here!
|
||||
return x!!.size()
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?): kotlin.Int
|
||||
@@ -0,0 +1,6 @@
|
||||
fun calc(x: List<String>?, y: List<Int>?) {
|
||||
// x and y should be non-null in arguments list, despite of a chains
|
||||
x?.subList(y?.subList(1, 2)?.get(<!DEBUG_INFO_SMARTCAST!>y<!>.size()) ?: 0,
|
||||
y?.get(0) ?: 1) // But safe call is NECESSARY here for y
|
||||
?.get(<!DEBUG_INFO_SMARTCAST!>x<!>.size())
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?, /*1*/ y: kotlin.List<kotlin.Int>?): kotlin.Unit
|
||||
@@ -0,0 +1,6 @@
|
||||
fun calc(x: List<String>?): Int {
|
||||
// x should be non-null in arguments list, despite of a chain
|
||||
x?.subList(0, 1)<!UNSAFE_CALL!>.<!>get(<!DEBUG_INFO_SMARTCAST!>x<!>.size())
|
||||
// But not here!
|
||||
return x!!.size()
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?): kotlin.Int
|
||||
@@ -0,0 +1,6 @@
|
||||
fun calc(x: List<String>?): Int {
|
||||
// x should be non-null in arguments list, including inner call
|
||||
x?.get(<!DEBUG_INFO_SMARTCAST!>x<!>.get(<!DEBUG_INFO_SMARTCAST!>x<!>.size() - 1).length())
|
||||
// but not also here!
|
||||
return x<!UNSAFE_CALL!>.<!>size()
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?): kotlin.Int
|
||||
@@ -0,0 +1,6 @@
|
||||
fun String.foo(arg: Int) = this[arg]
|
||||
|
||||
fun calc(x: String?) {
|
||||
// x should be non-null in arguments list
|
||||
x?.foo(<!DEBUG_INFO_SMARTCAST!>x<!>.length() - 1)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.String?): kotlin.Unit
|
||||
internal fun kotlin.String.foo(/*0*/ arg: kotlin.Int): kotlin.Char
|
||||
@@ -0,0 +1,7 @@
|
||||
fun foo(y: Int) = y
|
||||
|
||||
fun calc(x: List<String>?): Int {
|
||||
foo(x!!.size())
|
||||
// Here we should have smart cast because of x!!, despite of KT-7204 fixed
|
||||
return <!DEBUG_INFO_SMARTCAST!>x<!>.size()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?): kotlin.Int
|
||||
internal fun foo(/*0*/ y: kotlin.Int): kotlin.Int
|
||||
@@ -0,0 +1,4 @@
|
||||
fun calc(x: List<String>?, y: Int?) {
|
||||
// Smart cast should work here despite of KT-7204 fixed
|
||||
x?.subList(0, y!!)?.get(<!DEBUG_INFO_SMARTCAST!>y<!>)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?, /*1*/ y: kotlin.Int?): kotlin.Unit
|
||||
@@ -0,0 +1,7 @@
|
||||
fun String.foo(y: Int) = y
|
||||
|
||||
fun calc(x: List<String>?): Int {
|
||||
"abc".foo(x!!.size())
|
||||
// Here we should have smart cast because of x!!, despite of KT-7204 fixed
|
||||
return <!DEBUG_INFO_SMARTCAST!>x<!>.size()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?): kotlin.Int
|
||||
internal fun kotlin.String.foo(/*0*/ y: kotlin.Int): kotlin.Int
|
||||
@@ -0,0 +1,5 @@
|
||||
fun calc(x: List<String>?, y: Int?): Int {
|
||||
x?.subList(y!! - 1, <!DEBUG_INFO_SMARTCAST!>y<!>)
|
||||
// y!! above should not provide smart cast here
|
||||
return <!TYPE_MISMATCH!>y<!>
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?, /*1*/ y: kotlin.Int?): kotlin.Int
|
||||
@@ -0,0 +1,8 @@
|
||||
fun foo(x: String): String? = x
|
||||
|
||||
fun calc(x: String?, y: String?): Int {
|
||||
// Smart cast because of y!! in receiver
|
||||
x?.subSequence(y!!.subSequence(0, 1).length(), <!DEBUG_INFO_SMARTCAST!>y<!>.length())
|
||||
// No smart cast possible
|
||||
return y<!UNSAFE_CALL!>.<!>length()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Int
|
||||
internal fun foo(/*0*/ x: kotlin.String): kotlin.String?
|
||||
@@ -0,0 +1,8 @@
|
||||
fun foo(y: Int): Int {
|
||||
return y + 1
|
||||
}
|
||||
|
||||
fun calc(x: List<String>?): Int {
|
||||
// x should be non-null in arguments list
|
||||
return foo(x?.get(<!DEBUG_INFO_SMARTCAST!>x<!>.size() - 1)!!.length())
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?): kotlin.Int
|
||||
internal fun foo(/*0*/ y: kotlin.Int): kotlin.Int
|
||||
@@ -0,0 +1,6 @@
|
||||
fun calc(x: List<String>?) {
|
||||
// x should be non-null in arguments list, despite of a chain
|
||||
x?.subList(0, <!DEBUG_INFO_SMARTCAST!>x<!>.size())?.
|
||||
subList(0, <!DEBUG_INFO_SMARTCAST!>x<!>.size())?.
|
||||
get(<!DEBUG_INFO_SMARTCAST!>x<!>.size())
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?): kotlin.Unit
|
||||
@@ -0,0 +1,6 @@
|
||||
data class MyClass(val x: String?)
|
||||
|
||||
fun foo(y: MyClass): Int {
|
||||
val z = y.x?.subSequence(0, <!DEBUG_INFO_SMARTCAST!>y.x<!>.length())
|
||||
return z?.length() ?: -1
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package
|
||||
|
||||
internal fun foo(/*0*/ y: MyClass): kotlin.Int
|
||||
|
||||
kotlin.data() internal final class MyClass {
|
||||
public constructor MyClass(/*0*/ x: kotlin.String?)
|
||||
internal final val x: kotlin.String?
|
||||
internal final /*synthesized*/ fun component1(): kotlin.String?
|
||||
public final /*synthesized*/ fun copy(/*0*/ x: kotlin.String? = ...): MyClass
|
||||
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fun foo(x: String): String? = x
|
||||
|
||||
fun calc(x: String?): Int {
|
||||
// Smart cast because of x!! in receiver
|
||||
foo(x!!)?.subSequence(0, <!DEBUG_INFO_SMARTCAST!>x<!>.length())
|
||||
// Smart cast because of x!! in receiver
|
||||
return <!DEBUG_INFO_SMARTCAST!>x<!>.length()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.String?): kotlin.Int
|
||||
internal fun foo(/*0*/ x: kotlin.String): kotlin.String?
|
||||
@@ -0,0 +1,8 @@
|
||||
fun foo(x: String): String? = x
|
||||
|
||||
fun calc(x: String?): Int {
|
||||
// Smart cast because of x!! in receiver
|
||||
foo(x!!)?.subSequence(0, <!DEBUG_INFO_SMARTCAST!>x<!>.length())?.length()
|
||||
// Smart cast because of x!! in receiver
|
||||
return <!DEBUG_INFO_SMARTCAST!>x<!>.length()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.String?): kotlin.Int
|
||||
internal fun foo(/*0*/ x: kotlin.String): kotlin.String?
|
||||
@@ -0,0 +1,8 @@
|
||||
fun foo(x: String): String? = x
|
||||
|
||||
fun calc(x: String?, y: Int?): Int {
|
||||
// Smart cast because of x!! in receiver
|
||||
foo(x!!)?.subSequence(y!!, <!DEBUG_INFO_SMARTCAST!>x<!>.length())?.length()
|
||||
// No smart cast possible
|
||||
return <!TYPE_MISMATCH!>y<!>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.Int?): kotlin.Int
|
||||
internal fun foo(/*0*/ x: kotlin.String): kotlin.String?
|
||||
@@ -0,0 +1,6 @@
|
||||
fun calc(x: List<String>?): Int {
|
||||
// x should be non-null in arguments list
|
||||
x?.get(<!DEBUG_INFO_SMARTCAST!>x<!>.size() - 1)
|
||||
// but not also here!
|
||||
return x<!UNSAFE_CALL!>.<!>size()
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?): kotlin.Int
|
||||
@@ -0,0 +1,6 @@
|
||||
fun calc(x: List<String>?): Int {
|
||||
// x should be non-null in arguments list
|
||||
x?.subList(<!DEBUG_INFO_SMARTCAST!>x<!>.size() - 1, <!DEBUG_INFO_SMARTCAST!>x<!>.size())
|
||||
// but not also here!
|
||||
return x<!UNSAFE_CALL!>.<!>size()
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun calc(/*0*/ x: kotlin.List<kotlin.String>?): kotlin.Int
|
||||
Reference in New Issue
Block a user