Effects: add diagnostic tests on contracts
- Make AbstractDiagnosticsTest dump function contracts - Add diagnostics tests on parsing contracts - Add diagnostics tests on smartcats in presence of functions with contracts - Add diagnostics tests on initialization and flow in presence of in-place called lambdas ========== Introduction of EffectSystem: 16/18
This commit is contained in:
Vendored
+86
@@ -0,0 +1,86 @@
|
||||
// !LANGUAGE: +ReturnsEffect
|
||||
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
|
||||
fun onlyTrue(b: Boolean): Boolean {
|
||||
contract {
|
||||
returns(true) implies (b)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
fun onlyFalse(b: Boolean): Boolean {
|
||||
contract {
|
||||
returns(false) implies (!b)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
fun trueAndFalse(b: Boolean): Boolean {
|
||||
contract {
|
||||
returns(true) implies (b)
|
||||
returns(false) implies (!b)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==== actual tests ====
|
||||
|
||||
fun useOnlyTrueInTrueBranch(x: Any?) {
|
||||
if (onlyTrue(x is String)) {
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||
}
|
||||
else {
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun useOnlyTrueInFalseBranch(x: Any?) {
|
||||
if (onlyTrue(x !is String)) {
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
else {
|
||||
// No smartcast here, we don't know that condition is false here
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun useOnlyFalseInTrueBranch(x: Any?) {
|
||||
if (onlyFalse(x is String)) {
|
||||
// No smartcast here, we don't know that condition is true here
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
else {
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun useOnlyFalseInFalseBranch(x: Any?) {
|
||||
if (onlyFalse(x !is String)) {
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
else {
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||
}
|
||||
}
|
||||
|
||||
fun useTrueAndFalseInTrueBranch(x: Any?) {
|
||||
if (trueAndFalse(x is String)) {
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||
}
|
||||
else {
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun useTrueAndFalseInFalseBranch(x: Any?) {
|
||||
if (trueAndFalse(x !is String)) {
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
else {
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||
}
|
||||
}
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
package
|
||||
|
||||
public fun onlyFalse(/*0*/ b: kotlin.Boolean): kotlin.Boolean
|
||||
Returns(FALSE) -> !b
|
||||
|
||||
public fun onlyTrue(/*0*/ b: kotlin.Boolean): kotlin.Boolean
|
||||
Returns(TRUE) -> b
|
||||
|
||||
public fun trueAndFalse(/*0*/ b: kotlin.Boolean): kotlin.Boolean
|
||||
Returns(TRUE) -> b
|
||||
Returns(FALSE) -> !b
|
||||
|
||||
public fun useOnlyFalseInFalseBranch(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||
public fun useOnlyFalseInTrueBranch(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||
public fun useOnlyTrueInFalseBranch(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||
public fun useOnlyTrueInTrueBranch(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||
public fun useTrueAndFalseInFalseBranch(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||
public fun useTrueAndFalseInTrueBranch(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||
Vendored
+67
@@ -0,0 +1,67 @@
|
||||
// !LANGUAGE: +CallsInPlaceEffect +ReturnsEffect
|
||||
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
|
||||
fun callsAndInverts(b: Boolean, block: () -> Unit): Boolean {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
returns(true) implies (!b)
|
||||
returns(false) implies b
|
||||
}
|
||||
|
||||
block()
|
||||
return !b
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun smartcastAndInitialization(x: Any?) {
|
||||
val y: Int
|
||||
|
||||
if (callsAndInverts(x !is String) { y = 42 }) {
|
||||
println(y)
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||
} else {
|
||||
println(y)
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
println(y)
|
||||
}
|
||||
|
||||
fun inPresenceOfLazy(x: Any?, unknownBoolean: Boolean) {
|
||||
val y: Int
|
||||
|
||||
if (unknownBoolean && callsAndInverts(x !is String) { y = 42 }) {
|
||||
println(<!UNINITIALIZED_VARIABLE!>y<!>)
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||
}
|
||||
else {
|
||||
println(y)
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
println(y)
|
||||
}
|
||||
|
||||
fun isPresenceOfLazy2(x: Any?, unknownBoolean: Boolean) {
|
||||
val y: Int
|
||||
if (unknownBoolean && callsAndInverts(x !is String) { y = 42 }) {
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||
}
|
||||
else {
|
||||
println(<!UNINITIALIZED_VARIABLE!>y<!>)
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
println(y)
|
||||
}
|
||||
|
||||
fun isPresenceOfLazy3(x: Any?, unknownBoolean: Boolean) {
|
||||
val y: Int
|
||||
if (unknownBoolean && callsAndInverts(x !is String) { y = 42 }) {
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||
}
|
||||
else {
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
println(<!UNINITIALIZED_VARIABLE!>y<!>)
|
||||
}
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
public fun callsAndInverts(/*0*/ b: kotlin.Boolean, /*1*/ block: () -> kotlin.Unit): kotlin.Boolean
|
||||
CallsInPlace(block, EXACTLY_ONCE)
|
||||
Returns(TRUE) -> !b
|
||||
Returns(FALSE) -> b
|
||||
|
||||
public fun inPresenceOfLazy(/*0*/ x: kotlin.Any?, /*1*/ unknownBoolean: kotlin.Boolean): kotlin.Unit
|
||||
public fun isPresenceOfLazy2(/*0*/ x: kotlin.Any?, /*1*/ unknownBoolean: kotlin.Boolean): kotlin.Unit
|
||||
public fun isPresenceOfLazy3(/*0*/ x: kotlin.Any?, /*1*/ unknownBoolean: kotlin.Boolean): kotlin.Unit
|
||||
public fun smartcastAndInitialization(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||
Reference in New Issue
Block a user