[FIR-TEST] Add new testdata generated after changes in previous commit
This commit is contained in:
+28
@@ -0,0 +1,28 @@
|
||||
class Bar {
|
||||
fun next(): Bar? {
|
||||
if (2 == 4)
|
||||
return this
|
||||
else
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
fun foo(): Bar {
|
||||
var x: Bar? = Bar()
|
||||
var y: Bar?
|
||||
y = Bar()
|
||||
while (x != null) {
|
||||
// Here call is unsafe because of inner loop
|
||||
y.next()
|
||||
while (y != null) {
|
||||
if (x == y)
|
||||
// x is not null because of outer while
|
||||
return x
|
||||
// y is not null because of inner while
|
||||
y = y.next()
|
||||
}
|
||||
// x is not null because of outer while
|
||||
x = x.next()
|
||||
}
|
||||
return Bar()
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
fun foo() {
|
||||
var v: String? = null
|
||||
v.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
v = "abc"
|
||||
v.length
|
||||
v = null
|
||||
v.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
v = "abc"
|
||||
v.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
fun foo(arg: Int?) {
|
||||
val x = arg
|
||||
if (x != null) {
|
||||
arg.hashCode()
|
||||
}
|
||||
val y: Any? = arg
|
||||
if (y != null) {
|
||||
arg.hashCode()
|
||||
}
|
||||
val yy: Any?
|
||||
yy = arg
|
||||
if (yy != null) {
|
||||
arg.hashCode()
|
||||
}
|
||||
var z = arg
|
||||
z = z?.let { 42 }
|
||||
if (z != null) {
|
||||
arg.hashCode()
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
// KT-15792 and related
|
||||
|
||||
fun foo() {
|
||||
var x: String? = ""
|
||||
val y = x
|
||||
x = null
|
||||
if (y != null) {
|
||||
x.<!UNRESOLVED_REFERENCE!>hashCode<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun foo2() {
|
||||
var x: String? = ""
|
||||
val y = x
|
||||
if (y != null) {
|
||||
x.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
fun bar(s: String?) {
|
||||
var ss = s
|
||||
val hashCode = ss?.hashCode()
|
||||
ss = null
|
||||
if (hashCode != null) {
|
||||
ss.<!UNRESOLVED_REFERENCE!>hashCode<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun bar2(s: String?) {
|
||||
var ss = s
|
||||
val hashCode = ss?.hashCode()
|
||||
if (hashCode != null) {
|
||||
ss.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||
}
|
||||
}
|
||||
|
||||
class Some(var s: String?)
|
||||
|
||||
fun baz(arg: Some?) {
|
||||
val ss = arg?.s
|
||||
if (ss != null) {
|
||||
arg.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||
arg.<!INAPPLICABLE_CANDIDATE!>s<!>.<!UNRESOLVED_REFERENCE!>hashCode<!>()
|
||||
}
|
||||
}
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
// !LANGUAGE: +CapturedInClosureSmartCasts
|
||||
|
||||
fun run(f: () -> Unit) = f()
|
||||
|
||||
fun foo(s: String?) {
|
||||
var x: String? = null
|
||||
if (s != null) {
|
||||
x = s
|
||||
}
|
||||
if (x != null) {
|
||||
run {
|
||||
x.hashCode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun bar(s: String?) {
|
||||
var x = s
|
||||
if (x != null) {
|
||||
run {
|
||||
x.hashCode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun baz(s: String?) {
|
||||
var x = s
|
||||
if (x != null) {
|
||||
run {
|
||||
x.hashCode()
|
||||
}
|
||||
run {
|
||||
x.hashCode()
|
||||
x = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun gaz(s: String?) {
|
||||
var x = s
|
||||
if (x != null) {
|
||||
run {
|
||||
x.hashCode()
|
||||
x = null
|
||||
}
|
||||
run {
|
||||
x.hashCode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun gav(s: String?) {
|
||||
var x = s
|
||||
if (x != null) {
|
||||
run {
|
||||
x.hashCode()
|
||||
}
|
||||
x = null
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// !LANGUAGE: -CapturedInClosureSmartCasts
|
||||
|
||||
fun run(f: () -> Unit) = f()
|
||||
|
||||
fun foo(s: String?) {
|
||||
var x: String? = null
|
||||
if (s != null) {
|
||||
x = s
|
||||
}
|
||||
if (x != null) {
|
||||
run {
|
||||
x.hashCode()
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
data class SomeObject(val n: SomeObject?) {
|
||||
fun doSomething(): Boolean = true
|
||||
fun next(): SomeObject? = n
|
||||
}
|
||||
|
||||
|
||||
fun list(start: SomeObject) {
|
||||
var e: SomeObject?
|
||||
e = start
|
||||
do {
|
||||
// In theory smart cast is possible here
|
||||
// But in practice we have a loop with changing e
|
||||
// ?: should we "or" entrance type info with condition type info?
|
||||
if (!e.doSomething())
|
||||
break
|
||||
// Smart cast here is still not possible
|
||||
e = e.next()
|
||||
} while (e != null)
|
||||
// e can be null because of next()
|
||||
e.doSomething()
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(pp: String?): Int {
|
||||
var p = pp
|
||||
do {
|
||||
p!!.length
|
||||
if (p == "abc") break
|
||||
p = null
|
||||
} while (!x())
|
||||
// Smart cast is NOT possible here
|
||||
return p.length
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
data class SomeObject(val n: SomeObject?) {
|
||||
fun doSomething() {}
|
||||
fun next(): SomeObject? = n
|
||||
}
|
||||
|
||||
|
||||
fun list(start: SomeObject): SomeObject {
|
||||
var e: SomeObject? = start
|
||||
for (i in 0..42) {
|
||||
// Unsafe calls because of nullable e at the beginning
|
||||
e.<!INAPPLICABLE_CANDIDATE!>doSomething<!>()
|
||||
e = e.<!INAPPLICABLE_CANDIDATE!>next<!>()
|
||||
}
|
||||
// Smart cast is not possible here due to next()
|
||||
return e
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
data class SomeObject(val n: SomeObject?) {
|
||||
fun doSomething() {}
|
||||
fun next(): SomeObject? = n
|
||||
}
|
||||
|
||||
|
||||
fun list(start: SomeObject): SomeObject {
|
||||
var e: SomeObject? = start
|
||||
for (i in 0..42) {
|
||||
if (e == null)
|
||||
break
|
||||
// Smart casts are possible because of the break before
|
||||
e.doSomething()
|
||||
e = e.next()
|
||||
}
|
||||
return e
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
data class SomeObject(val n: SomeObject?) {
|
||||
fun doSomething() {}
|
||||
fun next(): SomeObject? = n
|
||||
}
|
||||
|
||||
|
||||
fun list(start: SomeObject): SomeObject {
|
||||
var e: SomeObject? = start
|
||||
for (i in 0..42) {
|
||||
if (e == null)
|
||||
continue
|
||||
// Smart casts are possible because of the continue before
|
||||
e.doSomething()
|
||||
e = e.next()
|
||||
}
|
||||
return e
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
public fun fooNotNull(s: String) {
|
||||
System.out.println("Length of $s is ${s.length}")
|
||||
}
|
||||
|
||||
public fun foo() {
|
||||
var s: String? = "not null"
|
||||
if (s != null)
|
||||
fooNotNull(s)
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// See KT-5737
|
||||
fun get(): String? {
|
||||
return "abc"
|
||||
}
|
||||
|
||||
fun foo(): Int {
|
||||
var ss:String? = get()
|
||||
|
||||
return if (ss != null && ss.length > 0)
|
||||
1
|
||||
else
|
||||
0
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
public fun fooNotNull(s: String) {
|
||||
System.out.println("Length of $s is ${s.length}")
|
||||
}
|
||||
|
||||
public fun foo() {
|
||||
var s: String? = "not null"
|
||||
if (s == null) {
|
||||
// Coming soon
|
||||
} else {
|
||||
fooNotNull(s)
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
public fun fooNotNull(s: String) {
|
||||
System.out.println("Length of $s is ${s.length}")
|
||||
}
|
||||
|
||||
public fun foo() {
|
||||
var s: String? = "not null"
|
||||
if (s == null) {
|
||||
return
|
||||
}
|
||||
fooNotNull(s)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// See KT-969
|
||||
fun f() {
|
||||
var s: String?
|
||||
s = "a"
|
||||
var s1 = "" // String � ?
|
||||
if (s != null) { // Redundant
|
||||
s1.length
|
||||
// We can do smartcast here and below
|
||||
s1 = s.toString() // return String?
|
||||
s1.length
|
||||
s1 = s
|
||||
s1.length
|
||||
// It's just an assignment without smartcast
|
||||
val s2 = s
|
||||
// But smartcast can be done here
|
||||
s2.length
|
||||
// And also here
|
||||
val s3 = s.toString()
|
||||
s3.length
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
data class SomeObject(val n: SomeObject?) {
|
||||
fun doSomething(): Boolean = true
|
||||
fun next(): SomeObject? = n
|
||||
}
|
||||
|
||||
|
||||
fun list(start: SomeObject) {
|
||||
var e: SomeObject?
|
||||
e = start
|
||||
// This comparison is senseless
|
||||
while (e != null) {
|
||||
// Smart cast because of the loop condition
|
||||
if (!e.doSomething())
|
||||
break
|
||||
// We still have smart cast here despite of a break
|
||||
e = e.next()
|
||||
}
|
||||
// e can be null because of next()
|
||||
e.doSomething()
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// See KT-774
|
||||
fun box() : Int {
|
||||
var a : Int? = 1
|
||||
var d = 1
|
||||
|
||||
if (a == null) {
|
||||
return 2
|
||||
} else {
|
||||
return a + d
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// See also KT-10735
|
||||
fun test() {
|
||||
var a: Int?
|
||||
try {
|
||||
a = 3
|
||||
}
|
||||
catch (e: Exception) {
|
||||
return
|
||||
}
|
||||
a.hashCode() // a is never null here
|
||||
}
|
||||
class A: Exception()
|
||||
class B: Exception()
|
||||
fun test2() {
|
||||
var a: Int?
|
||||
try {
|
||||
a = 4
|
||||
}
|
||||
catch (e: A) {
|
||||
return
|
||||
}
|
||||
catch (e: B) {
|
||||
return
|
||||
}
|
||||
a.hashCode() // a is never null here
|
||||
}
|
||||
fun test3() {
|
||||
var a: Int? = null
|
||||
try {
|
||||
a = 5
|
||||
}
|
||||
catch (e: A) {
|
||||
// do nothing
|
||||
}
|
||||
catch (e: B) {
|
||||
return
|
||||
}
|
||||
a.hashCode() // a is nullable here
|
||||
}
|
||||
fun test4() {
|
||||
var a: Int? = null
|
||||
try {
|
||||
// do nothing
|
||||
}
|
||||
catch (e: A) {
|
||||
return
|
||||
}
|
||||
catch (e: B) {
|
||||
return
|
||||
}
|
||||
a.<!INAPPLICABLE_CANDIDATE!>hashCode<!>() // a is nullable here
|
||||
}
|
||||
fun test5() {
|
||||
var a: Int?// = null
|
||||
try {
|
||||
a = 3
|
||||
}
|
||||
catch (e: Exception) {
|
||||
return
|
||||
}
|
||||
finally {
|
||||
a = 5
|
||||
}
|
||||
a.hashCode() // a is never null here
|
||||
}
|
||||
fun test6() {
|
||||
var a: Int?// = null
|
||||
try {
|
||||
a = 3
|
||||
}
|
||||
catch (e: Exception) {
|
||||
return
|
||||
}
|
||||
finally {
|
||||
a = null
|
||||
}
|
||||
a.<!UNRESOLVED_REFERENCE!>hashCode<!>() // a is null here
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
fun foo() {
|
||||
var v: String? = "xyz"
|
||||
// It is possible in principle to provide smart cast here
|
||||
v.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
v = null
|
||||
v.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
data class SomeObject(val n: SomeObject?) {
|
||||
fun doSomething() {}
|
||||
fun next(): SomeObject? = n
|
||||
}
|
||||
|
||||
|
||||
fun list(start: SomeObject) {
|
||||
var e: SomeObject? = start
|
||||
while (e != null) {
|
||||
// While condition makes both smart casts possible
|
||||
e.doSomething()
|
||||
e = e.next()
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(pp: String?, rr: String?): Int {
|
||||
var p = pp
|
||||
var r = rr
|
||||
do {
|
||||
do {
|
||||
p!!.length
|
||||
} while (r == null)
|
||||
} while (!x())
|
||||
// Auto cast possible
|
||||
r.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
// Auto cast possible
|
||||
return p.length
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(qq: String?): Int {
|
||||
var q = qq
|
||||
while(true) {
|
||||
q!!.length
|
||||
var r = q
|
||||
do {
|
||||
var p = r
|
||||
do {
|
||||
// p = r, r = q and q is not null
|
||||
p.length
|
||||
} while (!x())
|
||||
} while (r == null) // r = q and q is not null
|
||||
if (!x()) break
|
||||
}
|
||||
// Smart cast is possible
|
||||
return q.length
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
class Bar {
|
||||
fun next(): Bar? {
|
||||
if (2 == 4)
|
||||
return this
|
||||
else
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
fun foo(): Bar {
|
||||
var x: Bar? = Bar()
|
||||
var y: Bar? = Bar()
|
||||
while (x != null) {
|
||||
// Here call is unsafe because of initialization and also inner loop
|
||||
y.<!INAPPLICABLE_CANDIDATE!>next<!>()
|
||||
while (y != null) {
|
||||
if (x == y)
|
||||
// x is not null because of outer while
|
||||
return x
|
||||
// y is not null because of inner while
|
||||
y = y.next()
|
||||
}
|
||||
// x is not null because of outer while
|
||||
x = x.next()
|
||||
}
|
||||
return Bar()
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
fun foo(arg: Int?): Int {
|
||||
var i = arg
|
||||
if (i != null && i++ == 5) {
|
||||
return i-- + i
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
operator fun Long?.inc() = this?.let { it + 1 }
|
||||
|
||||
fun bar(arg: Long?): Long {
|
||||
var i = arg
|
||||
if (i++ == 5L) {
|
||||
return i<!INAPPLICABLE_CANDIDATE!>--<!> + i
|
||||
}
|
||||
if (i++ == 7L) {
|
||||
return i++ <!INAPPLICABLE_CANDIDATE!>+<!> i
|
||||
}
|
||||
return 0L
|
||||
}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
class MyClass
|
||||
|
||||
operator fun MyClass.inc(): MyClass { return null!! }
|
||||
|
||||
public fun box() : MyClass? {
|
||||
var i : MyClass?
|
||||
i = MyClass()
|
||||
// type of j can be inferred as MyClass()
|
||||
var j = i++
|
||||
j.hashCode()
|
||||
return i
|
||||
}
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
class MyClass
|
||||
|
||||
// Correct at compile time but wrong at run-time
|
||||
operator fun MyClass?.inc(): MyClass? { return null }
|
||||
|
||||
public fun box() : MyClass? {
|
||||
var i : MyClass?
|
||||
i = MyClass()
|
||||
var j = i++
|
||||
j.hashCode()
|
||||
return i
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
operator fun Int?.inc(): Int? { return this }
|
||||
|
||||
public fun box(arg: Int?) : Int? {
|
||||
var i : Int? = arg
|
||||
var j = i++
|
||||
j.<!INAPPLICABLE_CANDIDATE!>toInt<!>()
|
||||
return i
|
||||
}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
class MyClass
|
||||
|
||||
operator fun MyClass.inc(): MyClass { return null!! }
|
||||
|
||||
public fun box() {
|
||||
var i : MyClass?
|
||||
i = MyClass()
|
||||
// Type of j should be inferred as MyClass?
|
||||
var j = ++i
|
||||
// j is null so call is unsafe
|
||||
j.hashCode()
|
||||
}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
class MyClass
|
||||
|
||||
// Correct at compile time but wrong at run-time
|
||||
operator fun MyClass?.inc(): MyClass? { return null }
|
||||
|
||||
public fun box() {
|
||||
var i : MyClass?
|
||||
i = MyClass()
|
||||
// type of j should be MyClass?
|
||||
var j = ++i
|
||||
// j is null so call should be unsafe
|
||||
j.hashCode()
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
operator fun Int?.inc(): Int? { return this }
|
||||
|
||||
public fun box(arg: Int?) : Int? {
|
||||
var i = arg
|
||||
var j = ++i
|
||||
j.<!INAPPLICABLE_CANDIDATE!>toInt<!>()
|
||||
return ++j
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// !LANGUAGE: +SoundSmartCastsAfterTry
|
||||
|
||||
fun bar(arg: Any?) = arg
|
||||
|
||||
fun foo() {
|
||||
var s: String?
|
||||
s = null
|
||||
try {
|
||||
s = "Test"
|
||||
} catch (ex: Exception) {}
|
||||
bar(s)
|
||||
if (s != null) { }
|
||||
s.<!UNRESOLVED_REFERENCE!>hashCode<!>()
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// !LANGUAGE: +SoundSmartCastsAfterTry
|
||||
|
||||
fun foo() {
|
||||
var s: String?
|
||||
s = "Test"
|
||||
try {
|
||||
s = null
|
||||
} catch (ex: Exception) {}
|
||||
s.<!UNRESOLVED_REFERENCE!>hashCode<!>()
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// !LANGUAGE: +SoundSmartCastsAfterTry
|
||||
|
||||
fun bar() {}
|
||||
|
||||
fun foo() {
|
||||
var s: String?
|
||||
s = "Test"
|
||||
try {
|
||||
s = null
|
||||
}
|
||||
catch (ex: Exception) {}
|
||||
finally {
|
||||
bar()
|
||||
}
|
||||
s.<!UNRESOLVED_REFERENCE!>hashCode<!>()
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// !LANGUAGE: -SoundSmartCastsAfterTry
|
||||
|
||||
fun foo() {
|
||||
var s: String?
|
||||
s = "Test"
|
||||
try {
|
||||
s = null
|
||||
} catch (ex: Exception) {}
|
||||
s.<!UNRESOLVED_REFERENCE!>hashCode<!>()
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// !LANGUAGE: +SoundSmartCastsAfterTry
|
||||
|
||||
fun foo() {
|
||||
var s: String?
|
||||
s = "Test"
|
||||
try {
|
||||
s = "Other"
|
||||
} catch (ex: Exception) {}
|
||||
// Problem: here we do not see that 's' is always not-null
|
||||
s.hashCode()
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// FILE: J.java
|
||||
|
||||
class J {
|
||||
static String foo() { return "abc"; }
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
fun bar() {
|
||||
var v: String?
|
||||
v = J.foo()
|
||||
v.length
|
||||
gav(v)
|
||||
}
|
||||
|
||||
fun gav(v: String) = v
|
||||
@@ -0,0 +1,12 @@
|
||||
fun String?.foo(): String {
|
||||
return this ?: ""
|
||||
}
|
||||
|
||||
class MyClass {
|
||||
private var s: String? = null
|
||||
|
||||
fun bar(): String {
|
||||
s = "42"
|
||||
return s.foo()
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fun String?.foo(): String {
|
||||
return this ?: ""
|
||||
}
|
||||
|
||||
class MyClass {
|
||||
fun bar(): String {
|
||||
var s: String? = null
|
||||
if (4 < 2)
|
||||
s = "42"
|
||||
return s.foo()
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
fun create(): Map<String, String> = null!!
|
||||
|
||||
operator fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> = null!!
|
||||
|
||||
operator fun <K, V> Map.Entry<K, V>.component1() = key
|
||||
|
||||
operator fun <K, V> Map.Entry<K, V>.component2() = value
|
||||
|
||||
class MyClass {
|
||||
private var m: Map<String, String>? = null
|
||||
fun foo(): Int {
|
||||
var res = 0
|
||||
m = create()
|
||||
// See KT-7428
|
||||
for ((k, v) in m)
|
||||
res += (k.length + v.length)
|
||||
return res
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
public fun foo() {
|
||||
var s: String? = ""
|
||||
fun closure(): Int {
|
||||
if (s == "") {
|
||||
s = null
|
||||
return -1
|
||||
} else if (s == null) {
|
||||
return -2
|
||||
} else {
|
||||
return s.length // Here smartcast is possible, at least in principle
|
||||
}
|
||||
}
|
||||
if (s != null) {
|
||||
System.out.println(closure())
|
||||
System.out.println(s.length) // Here smartcast is not possible due to a closure predecessor
|
||||
}
|
||||
}
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
// See also KT-7186
|
||||
|
||||
fun IntArray.forEachIndexed( op: (i: Int, value: Int) -> Unit) {
|
||||
for (i in 0..this.size)
|
||||
op(i, this[i])
|
||||
}
|
||||
|
||||
fun max(a: IntArray): Int? {
|
||||
var maxI: Int? = null
|
||||
a.forEachIndexed { i, value ->
|
||||
if (maxI == null || value >= a[maxI])
|
||||
maxI = i
|
||||
}
|
||||
return maxI
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
public fun foo() {
|
||||
var s: String? = ""
|
||||
fun closure(): Int {
|
||||
if (s == null) {
|
||||
return -1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
if (s != null) {
|
||||
System.out.println(closure())
|
||||
// Smart cast is possible, nobody modifies s
|
||||
System.out.println(s.length)
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
public fun foo() {
|
||||
var i: Int? = 1
|
||||
if (i != null) {
|
||||
while (i != 10) {
|
||||
i++ // Here smart cast should not be performed due to a successor
|
||||
i = null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fun get(): String? {
|
||||
return ""
|
||||
}
|
||||
|
||||
fun foo(): Int {
|
||||
var c: String? = get()
|
||||
c!!.length
|
||||
return c.length // Previous line should make !! unnecessary here.
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
fun foo(): Int {
|
||||
var i: Int? = 42
|
||||
i = null
|
||||
return i + 1
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
public fun foo() {
|
||||
var i: Int? = 1
|
||||
if (i != null) {
|
||||
while (i != 10) {
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
fun foo(): Int {
|
||||
var s: String? = "abc"
|
||||
s = null
|
||||
return s.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(pp: String?): Int {
|
||||
var p = pp
|
||||
while(true) {
|
||||
p!!.length
|
||||
if (x()) break
|
||||
p = null
|
||||
}
|
||||
// Smart cast is NOT possible here
|
||||
// (we could provide it but p = null makes it much harder)
|
||||
return p.length
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(pp: String?): Int {
|
||||
var p = pp
|
||||
while(true) {
|
||||
p!!.length
|
||||
if (x()) break
|
||||
(((p))) = null
|
||||
}
|
||||
// Smart cast is NOT possible here
|
||||
// (we could provide it but p = null makes it much harder)
|
||||
return p.length
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(pp: String?): Int {
|
||||
var p = pp
|
||||
while(true) {
|
||||
p!!.length
|
||||
if (x()) break
|
||||
(p) = null
|
||||
}
|
||||
// Smart cast is NOT possible here
|
||||
// (we could provide it but p = null makes it much harder)
|
||||
return p.length
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
data class SomeObject(val n: SomeObject?) {
|
||||
fun doSomething(): Boolean = true
|
||||
fun next(): SomeObject? = n
|
||||
}
|
||||
|
||||
fun list(start: SomeObject) {
|
||||
var e: SomeObject? = start
|
||||
while (e != null) {
|
||||
// Smart cast due to the loop condition
|
||||
if (!e.doSomething())
|
||||
break
|
||||
// We still have smart cast here despite of a break
|
||||
e = e.next()
|
||||
}
|
||||
// e can be null because of next()
|
||||
e.doSomething()
|
||||
}
|
||||
Reference in New Issue
Block a user