Data flow information is no longer dropped while analyzing object literal expression. #KT-6293 Fixed. #KT-7110 Fixed.
A set of tests for KT-6293 / KT-7110 provided.
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
// See KT-6293: Smart cast doesn't work after object literal
|
||||
abstract class Runnable {
|
||||
abstract fun run()
|
||||
}
|
||||
|
||||
fun foo(): Int {
|
||||
val c: Int? = null
|
||||
if (c is Int) {
|
||||
var k: Runnable
|
||||
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
|
||||
k = object: Runnable() {
|
||||
override fun run() = Unit
|
||||
}
|
||||
// Unnecessary but not important smart cast
|
||||
<!DEBUG_INFO_SMARTCAST!>k<!>.run()
|
||||
return <!DEBUG_INFO_SMARTCAST!>c<!> + d
|
||||
}
|
||||
else return -1
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
internal fun foo(): kotlin.Int
|
||||
|
||||
internal abstract class Runnable {
|
||||
public constructor Runnable()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
internal abstract fun run(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// See KT-6293: Smart cast doesn't work after object literal
|
||||
abstract class Runnable {
|
||||
abstract fun run()
|
||||
}
|
||||
|
||||
fun foo(): Int {
|
||||
val c: Int? = null
|
||||
if (c is Int) {
|
||||
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
|
||||
// This object breaks data flow info propagation
|
||||
val k = object: Runnable() {
|
||||
override fun run() = Unit
|
||||
}
|
||||
k.run()
|
||||
// Smart cast should work but error is reported
|
||||
return <!DEBUG_INFO_SMARTCAST!>c<!> + d
|
||||
}
|
||||
else return -1
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
internal fun foo(): kotlin.Int
|
||||
|
||||
internal abstract class Runnable {
|
||||
public constructor Runnable()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
internal abstract fun run(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
abstract class Runnable {
|
||||
abstract fun run()
|
||||
}
|
||||
|
||||
fun foo(): Int {
|
||||
val c: Int? = null
|
||||
var a: Int?
|
||||
if (c is Int) {
|
||||
a = 2
|
||||
val k = object: Runnable() {
|
||||
init {
|
||||
a = null
|
||||
}
|
||||
override fun run() = Unit
|
||||
}
|
||||
k.run()
|
||||
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
|
||||
// a is captured so smart cast is not possible
|
||||
return d + <!SMARTCAST_IMPOSSIBLE!>a<!>
|
||||
}
|
||||
else return -1
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
internal fun foo(): kotlin.Int
|
||||
|
||||
internal abstract class Runnable {
|
||||
public constructor Runnable()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
internal abstract fun run(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
abstract class Runnable {
|
||||
abstract fun run()
|
||||
}
|
||||
|
||||
fun foo(): Int {
|
||||
val c: Int? = null
|
||||
val a: Int? = 1
|
||||
if (c is Int) {
|
||||
val k = object: Runnable() {
|
||||
init {
|
||||
a!!.toInt()
|
||||
}
|
||||
override fun run() = Unit
|
||||
}
|
||||
k.run()
|
||||
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
|
||||
// a is not null because of k constructor, but we do not know it
|
||||
return a <!UNSAFE_INFIX_CALL!>+<!> d
|
||||
}
|
||||
else return -1
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
internal fun foo(): kotlin.Int
|
||||
|
||||
internal abstract class Runnable {
|
||||
public constructor Runnable()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
internal abstract fun run(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
abstract class Runnable(val arg: Int) {
|
||||
abstract fun run(): Int
|
||||
}
|
||||
|
||||
fun foo(): Int {
|
||||
val c: Int? = null
|
||||
val a: Int? = 1
|
||||
if (c is Int) {
|
||||
val k = object: Runnable(a!!) {
|
||||
override fun run() = arg
|
||||
}
|
||||
k.run()
|
||||
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
|
||||
return <!DEBUG_INFO_SMARTCAST!>a<!> + d
|
||||
}
|
||||
else return -1
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package
|
||||
|
||||
internal fun foo(): kotlin.Int
|
||||
|
||||
internal abstract class Runnable {
|
||||
public constructor Runnable(/*0*/ arg: kotlin.Int)
|
||||
internal final val arg: kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
internal abstract fun run(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
abstract class Runnable(val arg: Int) {
|
||||
abstract fun run(): Int
|
||||
}
|
||||
|
||||
interface Wrapper {
|
||||
fun run(): Int
|
||||
}
|
||||
|
||||
fun foo(): Int {
|
||||
val c: Int? = null
|
||||
val a: Int? = 1
|
||||
if (c is Int) {
|
||||
val k = object: Wrapper, Runnable(a!!) {
|
||||
override fun run() = arg
|
||||
}
|
||||
k.run()
|
||||
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
|
||||
return <!DEBUG_INFO_SMARTCAST!>a<!> + d
|
||||
}
|
||||
else return -1
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package
|
||||
|
||||
internal fun foo(): kotlin.Int
|
||||
|
||||
internal abstract class Runnable {
|
||||
public constructor Runnable(/*0*/ arg: kotlin.Int)
|
||||
internal final val arg: kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
internal abstract fun run(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
internal interface Wrapper {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
internal abstract fun run(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Anonymous object's initialization does not affect smart casts
|
||||
|
||||
abstract class A(val s: String) {
|
||||
fun bar(): String = s
|
||||
}
|
||||
|
||||
fun foo(o: String?): Int {
|
||||
val a = object : A(o!!){}
|
||||
a.bar()
|
||||
return <!DEBUG_INFO_SMARTCAST!>o<!>.length()
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package
|
||||
|
||||
internal fun foo(/*0*/ o: kotlin.String?): kotlin.Int
|
||||
|
||||
internal abstract class A {
|
||||
public constructor A(/*0*/ s: kotlin.String)
|
||||
internal final val s: kotlin.String
|
||||
internal final fun bar(): kotlin.String
|
||||
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,16 @@
|
||||
// See KT-6293: Smart cast doesn't work after object literal
|
||||
abstract class Runnable {
|
||||
abstract fun run()
|
||||
}
|
||||
|
||||
fun foo(): Int {
|
||||
val c: Int? = null
|
||||
if (c is Int) {
|
||||
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
|
||||
object: Runnable() {
|
||||
override fun run() = Unit
|
||||
}.run()
|
||||
return <!DEBUG_INFO_SMARTCAST!>c<!> + d
|
||||
}
|
||||
else return -1
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
internal fun foo(): kotlin.Int
|
||||
|
||||
internal abstract class Runnable {
|
||||
public constructor Runnable()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
internal abstract fun run(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
Reference in New Issue
Block a user