Files
kotlin-fork/compiler/testData/diagnostics/tests/infos/SmartCasts.kt
T
Mikhail Zarechenskiy bcc8802014 [NI] Avoid constraints from expected type for effectively empty system
Expression will be checked against expected type later.

 Theoretically, this is not very good, but it aligns with the old
 inference, plus it helps avoiding multiple type mismatch diagnostics.
2019-04-17 12:55:12 +03:00

229 lines
5.5 KiB
Kotlin
Vendored

// !WITH_NEW_INFERENCE
open class A() {
fun foo() {}
}
class B() : A() {
fun bar() {}
}
fun f9(init : A?) {
val a : A? = init
a?.foo()
a?.<!UNRESOLVED_REFERENCE!>bar<!>()
if (a is B) {
<!DEBUG_INFO_SMARTCAST!>a<!>.bar()
<!DEBUG_INFO_SMARTCAST!>a<!>.foo()
}
a?.foo()
a?.<!UNRESOLVED_REFERENCE!>bar<!>()
if (!(a is B)) {
a?.<!UNRESOLVED_REFERENCE!>bar<!>()
a?.foo()
}
if (!(a is B) || <!DEBUG_INFO_SMARTCAST!>a<!>.bar() == Unit) {
a?.<!UNRESOLVED_REFERENCE!>bar<!>()
}
if (!(a is B)) {
return;
}
<!DEBUG_INFO_SMARTCAST!>a<!>.bar()
<!DEBUG_INFO_SMARTCAST!>a<!>.foo()
}
fun f10(init : A?) {
val a : A? = init
if (!(a is B)) {
return;
}
if (!(<!USELESS_IS_CHECK!>a is B<!>)) {
return;
}
}
class C() : A() {
fun bar() {
}
}
fun f101(a : A?) {
if (a is C) {
<!DEBUG_INFO_SMARTCAST!>a<!>.bar();
}
}
fun f11(a : A?) {
when (a) {
is B -> <!DEBUG_INFO_SMARTCAST!>a<!>.bar()
is A -> <!DEBUG_INFO_SMARTCAST!>a<!>.foo()
is Any -> <!DEBUG_INFO_SMARTCAST!>a<!>.foo()
<!USELESS_IS_CHECK!>is Any?<!> -> a.<!UNRESOLVED_REFERENCE!>bar<!>()
else -> a?.foo()
}
}
fun f12(a : A?) {
when (a) {
is B -> <!DEBUG_INFO_SMARTCAST!>a<!>.bar()
is A -> <!DEBUG_INFO_SMARTCAST!>a<!>.foo()
is Any -> <!DEBUG_INFO_SMARTCAST!>a<!>.foo();
<!USELESS_IS_CHECK!>is Any?<!> -> a.<!UNRESOLVED_REFERENCE!>bar<!>()
is C -> <!DEBUG_INFO_SMARTCAST!>a<!>.bar()
else -> a?.foo()
}
if (<!USELESS_IS_CHECK!>a is Any?<!>) {
a?.<!UNRESOLVED_REFERENCE!>bar<!>()
}
if (a is B) {
<!DEBUG_INFO_SMARTCAST!>a<!>.foo()
<!DEBUG_INFO_SMARTCAST!>a<!>.bar()
}
}
fun f13(a : A?) {
if (a is B) {
<!DEBUG_INFO_SMARTCAST!>a<!>.foo()
<!DEBUG_INFO_SMARTCAST!>a<!>.bar()
}
else {
a?.foo()
<!UNRESOLVED_REFERENCE!>c<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>bar<!>()
}
a?.foo()
if (!(a is B)) {
a?.foo()
<!UNRESOLVED_REFERENCE!>c<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>bar<!>()
}
else {
<!DEBUG_INFO_SMARTCAST!>a<!>.foo()
<!UNRESOLVED_REFERENCE!>c<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>bar<!>()
}
a?.foo()
if (a is B && <!DEBUG_INFO_SMARTCAST!>a<!>.foo() == Unit) {
<!DEBUG_INFO_SMARTCAST!>a<!>.foo()
<!DEBUG_INFO_SMARTCAST!>a<!>.bar()
}
else {
a?.foo()
<!UNRESOLVED_REFERENCE!>c<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>bar<!>()
}
if (!(a is B) || !(a is C)) {
}
else {
}
if (!(a is B) || !(a is C)) {
}
if (!(a is B)) return
<!DEBUG_INFO_SMARTCAST!>a<!>.bar()
}
fun f14(a : A?) {
while (!(a is B)) {
}
<!DEBUG_INFO_SMARTCAST!>a<!>.bar()
}
fun f15(a : A?) {
do {
} while (!(a is B))
<!DEBUG_INFO_SMARTCAST!>a<!>.bar()
}
fun getStringLength(obj : Any) : Char? {
if (obj !is String)
return null
return <!DEBUG_INFO_SMARTCAST!>obj<!>.get(0) // no cast to String is needed
}
fun toInt(i: Int?): Int = if (i != null) <!DEBUG_INFO_SMARTCAST!>i<!> else 0
fun illegalWhenBody(a: Any): Int = <!NI;TYPE_MISMATCH!><!NO_ELSE_IN_WHEN!>when<!>(a) {
is Int -> <!DEBUG_INFO_SMARTCAST!>a<!>
is String -> <!OI;TYPE_MISMATCH!>a<!>
}<!>
fun illegalWhenBlock(a: Any): Int {
when(a) {
is Int -> return <!DEBUG_INFO_SMARTCAST!>a<!>
is String -> return <!TYPE_MISMATCH!>a<!>
}
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
fun declarations(a: Any?) {
if (a is String) {
val <!UNUSED_VARIABLE!>p4<!>: String = <!DEBUG_INFO_SMARTCAST!>a<!>
}
if (a is String?) {
if (a != null) {
val <!UNUSED_VARIABLE!>s<!>: String = <!DEBUG_INFO_SMARTCAST!>a<!>
}
}
if (a != null) {
if (a is String?) {
val <!UNUSED_VARIABLE!>s<!>: String = <!DEBUG_INFO_SMARTCAST!>a<!>
}
}
}
fun vars(a: Any?) {
var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>b<!>: Int = 0
if (a is Int) {
<!UNUSED_VALUE!>b =<!> <!DEBUG_INFO_SMARTCAST!>a<!>
}
}
fun returnFunctionLiteralBlock(a: Any?): Function0<Int> {
if (a is Int) return { <!DEBUG_INFO_SMARTCAST!>a<!> }
else return { 1 }
}
fun returnFunctionLiteral(a: Any?): Function0<Int> {
if (a is Int) return { -> <!DEBUG_INFO_SMARTCAST!>a<!> }
else return { -> 1 }
}
fun returnFunctionLiteralExpressionBody(a: Any?): Function0<Int> =
if (a is Int) { -> <!DEBUG_INFO_SMARTCAST!>a<!> }
else { -> 1 }
fun mergeSmartCasts(a: Any?) {
if (a is String || a is Int) {
a.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
<!DEBUG_INFO_SMARTCAST!>a<!>.toString()
}
if (a is Int || a is String) {
a.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
}
when (a) {
is String, is Any -> a.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
}
if (a is String && <!USELESS_IS_CHECK!>a is Any<!>) {
val <!UNUSED_VARIABLE!>i<!>: Int = <!DEBUG_INFO_SMARTCAST!>a<!>.compareTo("")
}
if (a is String && <!DEBUG_INFO_SMARTCAST!>a<!>.compareTo("") == 0) {}
if (a is String || a.<!UNRESOLVED_REFERENCE!>compareTo<!>("") <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>==<!> 0) {}
}
//mutability
fun f(): String {
var a: Any = 11
if (a is String) {
// a is a string, despite of being a variable
val <!UNUSED_VARIABLE!>i<!>: String = <!DEBUG_INFO_SMARTCAST!>a<!>
<!DEBUG_INFO_SMARTCAST!>a<!>.compareTo("f")
// Beginning from here a is captured in a closure but nobody modifies it
val <!UNUSED_VARIABLE!>f<!>: Function0<String> = { <!DEBUG_INFO_SMARTCAST!>a<!> }
return <!DEBUG_INFO_SMARTCAST!>a<!>
}
return ""
}
fun foo(aa: Any?): Int {
var a = aa
if (a is Int?) {
return <!TYPE_MISMATCH!>a<!>
}
return 1
}