[FIR] Track local variable assigned types for smartcast stability
When a lambda captures a local variable without a contract, future assignments can impact the smartcast stability for that variable within the lambda. Because future assignments can appear in both resolved and unresolved code, track each assignment as encountered. To determine if a smartcast can be considered stable, check that all future assignments are resolved and do not revert variable to a super type. ^KT-58191 Fixed
This commit is contained in:
Vendored
+1
-1
@@ -55,7 +55,7 @@ fun test4() {
|
||||
require(x is String)
|
||||
runWithoutContract {
|
||||
x = ""
|
||||
<!SMARTCAST_IMPOSSIBLE!>x<!>.length
|
||||
x.length
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -184,7 +184,7 @@ fun test15() {
|
||||
x = 10
|
||||
y = x
|
||||
y.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
y.<!UNRESOLVED_REFERENCE!>inc<!>()
|
||||
y.inc()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ fun test16(x: Any) {
|
||||
runWithoutContract {
|
||||
require(x is String)
|
||||
y = x
|
||||
<!SMARTCAST_IMPOSSIBLE!>y<!>.length
|
||||
y.length
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-3
@@ -1,3 +1,4 @@
|
||||
// SKIP_TXT
|
||||
// ISSUE: KT-55338
|
||||
|
||||
fun test_1() {
|
||||
@@ -8,7 +9,7 @@ fun test_1() {
|
||||
s = "hello"
|
||||
}
|
||||
s.length // smartcast in K1 and K2
|
||||
noInlineRun { <!SMARTCAST_IMPOSSIBLE!>s<!>.length } // smartcast in K1, unsafe call in K2 <------------
|
||||
noInlineRun { s.length } // smartcast in K1 and K2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +63,7 @@ fun test_3_2() {
|
||||
s = "world"
|
||||
}
|
||||
s.length // smartcast in K1 and K2
|
||||
noInlineRun { <!SMARTCAST_IMPOSSIBLE!>s<!>.length } // smartcast in K1, unsafe call in K2 <------------
|
||||
noInlineRun { s.length } // smartcast in K1 and K2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +91,18 @@ fun test_4_2() {
|
||||
s = getString()
|
||||
}
|
||||
s.length // smartcast in K1 and K2
|
||||
noInlineRun { <!SMARTCAST_IMPOSSIBLE!>s<!>.length } // smartcast in K1, unsafe call in K2 <------------
|
||||
noInlineRun { s.length } // smartcast in K1 and K2
|
||||
}
|
||||
}
|
||||
|
||||
fun test_5() {
|
||||
var s: String? = null
|
||||
|
||||
for (i in 1..10) {
|
||||
s = null
|
||||
s = getString()
|
||||
s.length // smartcast in K1 and K2
|
||||
noInlineRun { <!SMARTCAST_IMPOSSIBLE!>s<!>.length } // smartcast in K1, unsafe call in K2
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-3
@@ -1,3 +1,4 @@
|
||||
// SKIP_TXT
|
||||
// ISSUE: KT-55338
|
||||
|
||||
fun test_1() {
|
||||
@@ -8,7 +9,7 @@ fun test_1() {
|
||||
s = "hello"
|
||||
}
|
||||
<!DEBUG_INFO_SMARTCAST!>s<!>.length // smartcast in K1 and K2
|
||||
noInlineRun { <!DEBUG_INFO_SMARTCAST!>s<!>.length } // smartcast in K1, unsafe call in K2 <------------
|
||||
noInlineRun { <!DEBUG_INFO_SMARTCAST!>s<!>.length } // smartcast in K1 and K2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +63,7 @@ fun test_3_2() {
|
||||
s = "world"
|
||||
}
|
||||
<!DEBUG_INFO_SMARTCAST!>s<!>.length // smartcast in K1 and K2
|
||||
noInlineRun { <!DEBUG_INFO_SMARTCAST!>s<!>.length } // smartcast in K1, unsafe call in K2 <------------
|
||||
noInlineRun { <!DEBUG_INFO_SMARTCAST!>s<!>.length } // smartcast in K1 and K2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +91,18 @@ fun test_4_2() {
|
||||
s = getString()
|
||||
}
|
||||
<!DEBUG_INFO_SMARTCAST!>s<!>.length // smartcast in K1 and K2
|
||||
noInlineRun { <!DEBUG_INFO_SMARTCAST!>s<!>.length } // smartcast in K1, unsafe call in K2 <------------
|
||||
noInlineRun { <!DEBUG_INFO_SMARTCAST!>s<!>.length } // smartcast in K1 and K2
|
||||
}
|
||||
}
|
||||
|
||||
fun test_5() {
|
||||
var s: String? = <!VARIABLE_WITH_REDUNDANT_INITIALIZER!>null<!>
|
||||
|
||||
for (i in 1..10) {
|
||||
s = null
|
||||
s = getString()
|
||||
<!DEBUG_INFO_SMARTCAST!>s<!>.length // smartcast in K1 and K2
|
||||
noInlineRun { <!DEBUG_INFO_SMARTCAST!>s<!>.length } // smartcast in K1, unsafe call in K2
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
package
|
||||
|
||||
public fun getNullableString(): kotlin.String?
|
||||
public fun getString(): kotlin.String
|
||||
public fun noInlineRun(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||
public fun test_1(): kotlin.Unit
|
||||
public fun test_2_1(): kotlin.Unit
|
||||
public fun test_2_2(): kotlin.Unit
|
||||
public fun test_3_1(): kotlin.Unit
|
||||
public fun test_3_2(): kotlin.Unit
|
||||
public fun test_4_1(): kotlin.Unit
|
||||
public fun test_4_2(): kotlin.Unit
|
||||
Reference in New Issue
Block a user