Deprecate simplification of complex boolean constant expressions in whens and loops

^KT-39883 In Progress
This commit is contained in:
Dmitriy Novozhilov
2021-06-25 11:40:51 +03:00
committed by teamcityserver
parent 8a2e0cedf9
commit 05883afc0a
36 changed files with 641 additions and 46 deletions
@@ -4973,6 +4973,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/localObjectInConstructor.kt");
}
@Test
@TestMetadata("loopWithNonTrivialBooleanConst_error.kt")
public void testLoopWithNonTrivialBooleanConst_error() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/loopWithNonTrivialBooleanConst_error.kt");
}
@Test
@TestMetadata("loopWithNonTrivialBooleanConst_warning.kt")
public void testLoopWithNonTrivialBooleanConst_warning() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/loopWithNonTrivialBooleanConst_warning.kt");
}
@Test
@TestMetadata("mainWithWarningOnUnusedParam.kt")
public void testMainWithWarningOnUnusedParam() throws Exception {
@@ -30965,6 +30977,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/when/ExhaustiveBooleanNullable.kt");
}
@Test
@TestMetadata("exhaustiveBooleanWhenWithUntrivialConst_error.kt")
public void testExhaustiveBooleanWhenWithUntrivialConst_error() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/exhaustiveBooleanWhenWithUntrivialConst_error.kt");
}
@Test
@TestMetadata("exhaustiveBooleanWhenWithUntrivialConst_warning.kt")
public void testExhaustiveBooleanWhenWithUntrivialConst_warning() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/exhaustiveBooleanWhenWithUntrivialConst_warning.kt");
}
@Test
@TestMetadata("ExhaustiveBreakContinue.kt")
public void testExhaustiveBreakContinue() throws Exception {
@@ -4973,6 +4973,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/localObjectInConstructor.kt");
}
@Test
@TestMetadata("loopWithNonTrivialBooleanConst_error.kt")
public void testLoopWithNonTrivialBooleanConst_error() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/loopWithNonTrivialBooleanConst_error.kt");
}
@Test
@TestMetadata("loopWithNonTrivialBooleanConst_warning.kt")
public void testLoopWithNonTrivialBooleanConst_warning() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/loopWithNonTrivialBooleanConst_warning.kt");
}
@Test
@TestMetadata("mainWithWarningOnUnusedParam.kt")
public void testMainWithWarningOnUnusedParam() throws Exception {
@@ -30965,6 +30977,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/when/ExhaustiveBooleanNullable.kt");
}
@Test
@TestMetadata("exhaustiveBooleanWhenWithUntrivialConst_error.kt")
public void testExhaustiveBooleanWhenWithUntrivialConst_error() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/exhaustiveBooleanWhenWithUntrivialConst_error.kt");
}
@Test
@TestMetadata("exhaustiveBooleanWhenWithUntrivialConst_warning.kt")
public void testExhaustiveBooleanWhenWithUntrivialConst_warning() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/exhaustiveBooleanWhenWithUntrivialConst_warning.kt");
}
@Test
@TestMetadata("ExhaustiveBreakContinue.kt")
public void testExhaustiveBreakContinue() throws Exception {
@@ -1028,7 +1028,7 @@ public interface Errors {
DiagnosticFactory0<KtConstantExpression> UNSIGNED_LITERAL_WITHOUT_DECLARATIONS_ON_CLASSPATH = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtExpression> SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<KtExpression, KotlinType> INTEGER_OPERATOR_RESOLVE_WILL_CHANGE = DiagnosticFactory1.create(WARNING);
DiagnosticFactory1<KtExpression, Boolean> NON_TRIVIAL_BOOLEAN_CONSTANT = DiagnosticFactory1.create(WARNING);
// Casts and is-checks
@@ -439,6 +439,7 @@ public class DefaultErrorMessages {
MAP.put(UNSIGNED_LITERAL_WITHOUT_DECLARATIONS_ON_CLASSPATH, "Type of the constant expression cannot be resolved. Please make sure you have the required dependencies for unsigned types in the classpath");
MAP.put(SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED, "Conversion of signed constants to unsigned ones is prohibited");
MAP.put(INTEGER_OPERATOR_RESOLVE_WILL_CHANGE, "This expression will be resolved to {0} in further releases. Please add explicit convention call", RENDER_TYPE);
MAP.put(NON_TRIVIAL_BOOLEAN_CONSTANT, "Compiler won't reduce this expression to {0} in future. Please replace it with boolean literal", TO_STRING);
MAP.put(RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS, "Left-hand side of callable reference matches expression syntax reserved for future releases");
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.types.isError
import org.jetbrains.kotlin.types.typeUtil.isBoolean
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.util.OperatorNameConventions
import java.math.BigInteger
@@ -387,12 +388,39 @@ private class ConstantExpressionEvaluatorVisitor(
val compileTimeConstant = expression.accept(this, expectedType ?: TypeUtils.NO_EXPECTED_TYPE)
if (compileTimeConstant != null) {
if (shouldSkipComplexBooleanValue(expression, compileTimeConstant)) {
return null
}
trace.record(BindingContext.COMPILE_TIME_VALUE, expression, compileTimeConstant)
return compileTimeConstant
}
return null
}
@Suppress("warnings")
private fun shouldSkipComplexBooleanValue(
expression: KtExpression,
constant: CompileTimeConstant<*>
): Boolean {
if (constant.isError) return false
val constantValue = constant.toConstantValue(builtIns.booleanType)
if (!constantValue.getType(constantExpressionEvaluator.module).isBoolean()) return false
if (expression is KtConstantExpression || constant.parameters.usesVariableAsConstant) return false
if (languageVersionSettings.supportsFeature(LanguageFeature.ProhibitSimplificationOfNonTrivialConstBooleanExpressions)) {
return true
} else {
val parent = expression.parent
if (
parent is KtWhenConditionWithExpression ||
parent is KtContainerNode && (parent.parent is KtWhileExpression || parent.parent is KtDoWhileExpression)
) {
trace.report(Errors.NON_TRIVIAL_BOOLEAN_CONSTANT.on(expression, constantValue.value as Boolean))
}
return false
}
}
private val stringExpressionEvaluator = object : KtVisitor<TypedCompileTimeConstant<String>, Nothing?>() {
private fun createStringConstant(compileTimeConstant: CompileTimeConstant<*>): TypedCompileTimeConstant<String>? {
val constantValue = compileTimeConstant.toConstantValue(TypeUtils.NO_EXPECTED_TYPE)
+2 -1
View File
@@ -1,4 +1,5 @@
// FIR_IDENTICAL
// LANGUAGE: +ProhibitSimplificationOfNonTrivialConstBooleanExpressions
fun test() {
@ann
while (2 < 1) {}
@@ -10,4 +11,4 @@ fun test() {
for (i in 1..2) {}
}
annotation class ann
annotation class ann
@@ -1,3 +1,4 @@
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
fun test() {
@ann
while (2 > 1) {}
@@ -9,4 +10,4 @@ fun test() {
for (i in 1..2) {}
}
annotation class ann
annotation class ann
@@ -1,12 +1,13 @@
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
fun test() {
@ann
while (2 > 1) {}
while (<!NON_TRIVIAL_BOOLEAN_CONSTANT!>2 > 1<!>) {}
@ann
<!UNREACHABLE_CODE!>do {} while (2 > 1)<!>
<!UNREACHABLE_CODE!>do {} while (<!NON_TRIVIAL_BOOLEAN_CONSTANT!>2 > 1<!>)<!>
@ann
<!UNREACHABLE_CODE!>for (i in 1..2) {}<!>
}
annotation class ann
annotation class ann
@@ -1,3 +1,4 @@
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
fun t1() : Int{
@@ -1,3 +1,4 @@
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
fun t1() : Int{
@@ -68,12 +69,12 @@ fun t5() : Int {
return 1
<!UNREACHABLE_CODE!>2<!>
}
while (<!UNREACHABLE_CODE!>1 > 2<!>)
while (<!NON_TRIVIAL_BOOLEAN_CONSTANT, UNREACHABLE_CODE!>1 > 2<!>)
<!UNREACHABLE_CODE!>return 1<!>
}
fun t6() : Int {
while (1 > 2) {
while (<!NON_TRIVIAL_BOOLEAN_CONSTANT!>1 > 2<!>) {
return 1
<!UNREACHABLE_CODE!>2<!>
}
@@ -81,7 +82,7 @@ fun t6() : Int {
}
fun t6break() : Int {
while (1 > 2) {
while (<!NON_TRIVIAL_BOOLEAN_CONSTANT!>1 > 2<!>) {
break
<!UNREACHABLE_CODE!>2<!>
}
@@ -1,3 +1,4 @@
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
fun unreachable() {}
fun a() {
@@ -52,4 +53,4 @@ fun h(): Int {
while (true) {
if (true) return 12
}
} // should work
} // should work
@@ -1,3 +1,4 @@
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
fun unreachable() {}
fun a() {
@@ -13,11 +14,11 @@ fun b() {
}
fun c() {
do {} while (1 == 1)
do {} while (<!NON_TRIVIAL_BOOLEAN_CONSTANT!>1 == 1<!>)
}
fun d() {
while (2 == 2) {}
while (<!NON_TRIVIAL_BOOLEAN_CONSTANT!>2 == 2<!>) {}
}
fun use(arg: Any) = arg
@@ -52,4 +53,4 @@ fun h(): Int {
while (true) {
if (true) return 12
}
} // should work
} // should work
@@ -0,0 +1,72 @@
// LANGUAGE: +ProhibitSimplificationOfNonTrivialConstBooleanExpressions
// DIAGNOSTICS: -UNUSED_VARIABLE
fun test_1() {
while (true) {
}
val x = 1
}
fun test_2() {
while (true || false) {
}
val x = 1
}
fun test_3() {
while (1 == 1) {
}
val x = 1
}
fun test_4() {
while (false) {
val x = 1
}
val y = 2
}
fun test_5() {
while (false && true) {
val x = 1
}
val y = 2
}
fun test_6() {
do {
} while (true)
val x = 1
}
fun test_7() {
do {
} while (true || false)
val x = 1
}
fun test_8() {
do {
} while (1 == 1)
val x = 1
}
fun test_9() {
do {
val x = 1
} while (false)
val y = 2
}
fun test_10() {
do {
val x = 1
} while (false && true)
val y = 2
}
@@ -0,0 +1,73 @@
// LANGUAGE: +ProhibitSimplificationOfNonTrivialConstBooleanExpressions
// DIAGNOSTICS: -UNUSED_VARIABLE
fun test_1() {
while (true) {
}
<!UNREACHABLE_CODE!>val x = 1<!>
}
fun test_2() {
while (true || false) {
}
val x = 1
}
fun test_3() {
while (1 == 1) {
}
val x = 1
}
fun test_4() {
while (false) {
val x = 1
}
val y = 2
}
fun test_5() {
while (false && true) {
val x = 1
}
val y = 2
}
fun test_6() {
do {
} while (true)
<!UNREACHABLE_CODE!>val x = 1<!>
}
fun test_7() {
do {
} while (true || false)
val x = 1
}
fun test_8() {
do {
} while (1 == 1)
val x = 1
}
fun test_9() {
do {
val x = 1
} while (false)
val y = 2
}
fun test_10() {
do {
val x = 1
} while (false && true)
val y = 2
}
@@ -0,0 +1,13 @@
package
public fun test_1(): kotlin.Unit
public fun test_10(): kotlin.Unit
public fun test_2(): kotlin.Unit
public fun test_3(): kotlin.Unit
public fun test_4(): kotlin.Unit
public fun test_5(): kotlin.Unit
public fun test_6(): kotlin.Unit
public fun test_7(): kotlin.Unit
public fun test_8(): kotlin.Unit
public fun test_9(): kotlin.Unit
@@ -0,0 +1,72 @@
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
// DIAGNOSTICS: -UNUSED_VARIABLE
fun test_1() {
while (true) {
}
val x = 1
}
fun test_2() {
while (true || false) {
}
val x = 1
}
fun test_3() {
while (1 == 1) {
}
val x = 1
}
fun test_4() {
while (false) {
val x = 1
}
val y = 2
}
fun test_5() {
while (false && true) {
val x = 1
}
val y = 2
}
fun test_6() {
do {
} while (true)
val x = 1
}
fun test_7() {
do {
} while (true || false)
val x = 1
}
fun test_8() {
do {
} while (1 == 1)
val x = 1
}
fun test_9() {
do {
val x = 1
} while (false)
val y = 2
}
fun test_10() {
do {
val x = 1
} while (false && true)
val y = 2
}
@@ -0,0 +1,72 @@
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
// DIAGNOSTICS: -UNUSED_VARIABLE
fun test_1() {
while (true) {
}
<!UNREACHABLE_CODE!>val x = 1<!>
}
fun test_2() {
while (<!NON_TRIVIAL_BOOLEAN_CONSTANT!>true || false<!>) {
}
<!UNREACHABLE_CODE!>val x = 1<!>
}
fun test_3() {
while (<!NON_TRIVIAL_BOOLEAN_CONSTANT!>1 == 1<!>) {
}
<!UNREACHABLE_CODE!>val x = 1<!>
}
fun test_4() {
while (false) {
val x = 1
}
val y = 2
}
fun test_5() {
while (<!NON_TRIVIAL_BOOLEAN_CONSTANT!>false && true<!>) {
val x = 1
}
val y = 2
}
fun test_6() {
do {
} while (true)
<!UNREACHABLE_CODE!>val x = 1<!>
}
fun test_7() {
do {
} while (<!NON_TRIVIAL_BOOLEAN_CONSTANT!>true || false<!>)
<!UNREACHABLE_CODE!>val x = 1<!>
}
fun test_8() {
do {
} while (<!NON_TRIVIAL_BOOLEAN_CONSTANT!>1 == 1<!>)
<!UNREACHABLE_CODE!>val x = 1<!>
}
fun test_9() {
do {
val x = 1
} while (false)
val y = 2
}
fun test_10() {
do {
val x = 1
} while (<!NON_TRIVIAL_BOOLEAN_CONSTANT!>false && true<!>)
val y = 2
}
@@ -0,0 +1,13 @@
package
public fun test_1(): kotlin.Unit
public fun test_10(): kotlin.Unit
public fun test_2(): kotlin.Unit
public fun test_3(): kotlin.Unit
public fun test_4(): kotlin.Unit
public fun test_5(): kotlin.Unit
public fun test_6(): kotlin.Unit
public fun test_7(): kotlin.Unit
public fun test_8(): kotlin.Unit
public fun test_9(): kotlin.Unit
@@ -0,0 +1,12 @@
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
fun x(): Boolean { return true }
public fun foo(p: String?): Int {
// Like whileTrue but 2 == 2 is in use
while(2 == 2) {
p!!.length
if (x()) break
}
// Smart cast should not work in this case, see KT-6284
return p<!UNSAFE_CALL!>.<!>length
}
@@ -1,12 +1,12 @@
// FIR_IDENTICAL
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
fun x(): Boolean { return true }
public fun foo(p: String?): Int {
// Like whileTrue but 2 == 2 is in use
while(2 == 2) {
while(<!NON_TRIVIAL_BOOLEAN_CONSTANT!>2 == 2<!>) {
p!!.length
if (x()) break
}
// Smart cast should not work in this case, see KT-6284
return p<!UNSAFE_CALL!>.<!>length
}
}
@@ -1,18 +0,0 @@
/*
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
*
* SPEC VERSION: 0.1-313
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 3
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 4
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 5
*/
// See also: KT-3743
fun foo(arg: Boolean): String {
// Must be exhaustive
return <!NO_ELSE_IN_WHEN!>when<!>(arg) {
2 == 2 -> "truth"
2 == 1 -> "falsehood"
}
}
@@ -1,3 +1,5 @@
// FIR_IDENTICAL
// !LANGUAGE: +ProhibitSimplificationOfNonTrivialConstBooleanExpressions
/*
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
*
@@ -11,7 +13,7 @@
// See also: KT-3743
fun foo(arg: Boolean): String {
// Must be exhaustive
return when(arg) {
return <!NO_ELSE_IN_WHEN!>when<!>(arg) {
2 == 2 -> "truth"
2 == 1 -> "falsehood"
}
@@ -0,0 +1,32 @@
// FIR_IDENTICAL
// !LANGUAGE: +ProhibitSimplificationOfNonTrivialConstBooleanExpressions
// ISSUE: KT-39883
// Should always work
fun test_0(b: Boolean): String = when (b) {
true -> "true"
false -> "false"
}
// Deprecated
fun test_1(b: Boolean): String = <!NO_ELSE_IN_WHEN!>when<!> (b) {
1 == 1 -> "true"
"" != "" -> "false"
}
const val TRUE = true
// Already not working
fun test_2(b: Boolean): String = <!NO_ELSE_IN_WHEN!>when<!>(b) {
TRUE -> "true"
false -> "false"
}
const val s1 = "s1"
const val s2 = "s2"
// Already not working
fun test_3(b: Boolean): String = <!NO_ELSE_IN_WHEN!>when<!>(b) {
true -> "true"
s1 == s2 -> "false"
}
@@ -0,0 +1,9 @@
package
public const val TRUE: kotlin.Boolean = true
public const val s1: kotlin.String = "s1"
public const val s2: kotlin.String = "s2"
public fun test_0(/*0*/ b: kotlin.Boolean): kotlin.String
public fun test_1(/*0*/ b: kotlin.Boolean): kotlin.String
public fun test_2(/*0*/ b: kotlin.Boolean): kotlin.String
public fun test_3(/*0*/ b: kotlin.Boolean): kotlin.String
@@ -0,0 +1,31 @@
// !LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
// ISSUE: KT-39883
// Should always work
fun test_0(b: Boolean): String = when (b) {
true -> "true"
false -> "false"
}
// Deprecated
fun test_1(b: Boolean): String = <!NO_ELSE_IN_WHEN!>when<!> (b) {
1 == 1 -> "true"
"" != "" -> "false"
}
const val TRUE = true
// Already not working
fun test_2(b: Boolean): String = <!NO_ELSE_IN_WHEN!>when<!>(b) {
TRUE -> "true"
false -> "false"
}
const val s1 = "s1"
const val s2 = "s2"
// Already not working
fun test_3(b: Boolean): String = <!NO_ELSE_IN_WHEN!>when<!>(b) {
true -> "true"
s1 == s2 -> "false"
}
@@ -0,0 +1,31 @@
// !LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
// ISSUE: KT-39883
// Should always work
fun test_0(b: Boolean): String = when (b) {
true -> "true"
false -> "false"
}
// Deprecated
fun test_1(b: Boolean): String = when (b) {
<!NON_TRIVIAL_BOOLEAN_CONSTANT!>1 == 1<!> -> "true"
<!NON_TRIVIAL_BOOLEAN_CONSTANT!>"" != ""<!> -> "false"
}
const val TRUE = true
// Already not working
fun test_2(b: Boolean): String = <!NO_ELSE_IN_WHEN!>when<!>(b) {
TRUE -> "true"
false -> "false"
}
const val s1 = "s1"
const val s2 = "s2"
// Already not working
fun test_3(b: Boolean): String = <!NO_ELSE_IN_WHEN!>when<!>(b) {
true -> "true"
s1 == s2 -> "false"
}
@@ -0,0 +1,9 @@
package
public const val TRUE: kotlin.Boolean = true
public const val s1: kotlin.String = "s1"
public const val s2: kotlin.String = "s2"
public fun test_0(/*0*/ b: kotlin.Boolean): kotlin.String
public fun test_1(/*0*/ b: kotlin.Boolean): kotlin.String
public fun test_2(/*0*/ b: kotlin.Boolean): kotlin.String
public fun test_3(/*0*/ b: kotlin.Boolean): kotlin.String
@@ -4979,6 +4979,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/localObjectInConstructor.kt");
}
@Test
@TestMetadata("loopWithNonTrivialBooleanConst_error.kt")
public void testLoopWithNonTrivialBooleanConst_error() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/loopWithNonTrivialBooleanConst_error.kt");
}
@Test
@TestMetadata("loopWithNonTrivialBooleanConst_warning.kt")
public void testLoopWithNonTrivialBooleanConst_warning() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/loopWithNonTrivialBooleanConst_warning.kt");
}
@Test
@TestMetadata("mainWithWarningOnUnusedParam.kt")
public void testMainWithWarningOnUnusedParam() throws Exception {
@@ -31061,6 +31073,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/when/ExhaustiveBooleanNullable.kt");
}
@Test
@TestMetadata("exhaustiveBooleanWhenWithUntrivialConst_error.kt")
public void testExhaustiveBooleanWhenWithUntrivialConst_error() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/exhaustiveBooleanWhenWithUntrivialConst_error.kt");
}
@Test
@TestMetadata("exhaustiveBooleanWhenWithUntrivialConst_warning.kt")
public void testExhaustiveBooleanWhenWithUntrivialConst_warning() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/exhaustiveBooleanWhenWithUntrivialConst_warning.kt");
}
@Test
@TestMetadata("ExhaustiveBreakContinue.kt")
public void testExhaustiveBreakContinue() throws Exception {
@@ -1,4 +1,5 @@
// FIR_IDENTICAL
// LANGUAGE: +ProhibitSimplificationOfNonTrivialConstBooleanExpressions
// !DIAGNOSTICS: -UNUSED_EXPRESSION
// SKIP_TXT
@@ -26,3 +27,10 @@ fun case_2(value_1: Boolean?): String = <!NO_ELSE_IN_WHEN!>when<!>(value_1) {
// TESTCASE NUMBER: 3
fun case_3(value_1: Boolean?): Int = <!NO_ELSE_IN_WHEN!>when<!>(value_1) { }
// TESTCASE NUMBER: 4
fun case_4(value_1: Boolean?): String = <!NO_ELSE_IN_WHEN!>when<!> (value_1) {
true && false && ((true || false)) || true && !!!false && !!!true -> ""
true && false && ((true || false)) || true && !!!false -> ""
null -> ""
}
@@ -1,4 +1,5 @@
// FIR_IDENTICAL
// LANGUAGE: +ProhibitSimplificationOfNonTrivialConstBooleanExpressions
// !DIAGNOSTICS: -UNUSED_EXPRESSION
// SKIP_TXT
@@ -44,3 +45,10 @@ fun case_5(value_1: Boolean): String {
falseValue -> ""
}
}
// TESTCASE NUMBER: 6
fun case_6(value_1: Boolean): String = <!NO_ELSE_IN_WHEN!>when<!> (value_1) {
true && false && ((true || false)) || true && !!!false && !!!true -> ""
true && false && ((true || false)) || true && !!!false -> ""
}
@@ -1,4 +1,5 @@
// SKIP_TXT
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
/*
* KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE)
@@ -18,7 +19,7 @@ fun case_1(value_1: Boolean?): String = when (value_1) {
// TESTCASE NUMBER: 2
fun case_2(value_1: Boolean?): String = when (value_1) {
true && false && ((true || false)) || true && !!!false && !!!true -> ""
true && false && ((true || false)) || true && !!!false -> ""
<!NON_TRIVIAL_BOOLEAN_CONSTANT!>true && false && ((true || false)) || true && !!!false && !!!true<!> -> ""
<!NON_TRIVIAL_BOOLEAN_CONSTANT!>true && false && ((true || false)) || true && !!!false<!> -> ""
null -> ""
}
@@ -1,4 +1,5 @@
// SKIP_TXT
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
/*
* KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE)
@@ -17,6 +18,6 @@ fun case_1(value_1: Boolean): String = when (value_1) {
// TESTCASE NUMBER: 2
fun case_2(value_1: Boolean): String = when (value_1) {
true && false && ((true || false)) || true && !!!false && !!!true -> ""
true && false && ((true || false)) || true && !!!false -> ""
<!NON_TRIVIAL_BOOLEAN_CONSTANT!>true && false && ((true || false)) || true && !!!false && !!!true<!> -> ""
<!NON_TRIVIAL_BOOLEAN_CONSTANT!>true && false && ((true || false)) || true && !!!false<!> -> ""
}
@@ -1,4 +1,4 @@
// !LANGUAGE: +NewInference
// !LANGUAGE: +NewInference +ProhibitSimplificationOfNonTrivialConstBooleanExpressions
// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION
// SKIP_TXT
// FULL_JDK
@@ -66,4 +66,25 @@ sealed class SClass {
class A : SClass()
class B : SClass()
class C : SClass()
}
}
// TESTCASE NUMBER: 5
fun case5() {
val b = false
val when1: Any = when (b) {
false -> { }
!false -> { }
else -> { }
}
val when2: Any = <!NO_ELSE_IN_WHEN!>when<!> (b) {
false -> { }
!false -> { }
}
val when3: Any = <!NO_ELSE_IN_WHEN!>when<!> (b) {
false -> { }
<!DUPLICATE_LABEL_IN_WHEN!>false<!> -> { }
!false -> { }
}
}
@@ -1,4 +1,4 @@
// !LANGUAGE: +NewInference
// !LANGUAGE: +NewInference -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION
// SKIP_TXT
// FULL_JDK
@@ -47,18 +47,18 @@ fun case2() {
val b = false
val when1: Any = when (b) {
false -> { }
!false -> { }
<!NON_TRIVIAL_BOOLEAN_CONSTANT!>!false<!> -> { }
<!REDUNDANT_ELSE_IN_WHEN!>else<!> -> { }
}
val when2: Any = when (b) {
false -> { }
!false -> { }
<!NON_TRIVIAL_BOOLEAN_CONSTANT!>!false<!> -> { }
}
val when3: Any = when (b) {
false -> { }
<!DUPLICATE_LABEL_IN_WHEN!>false<!> -> { }
!false -> { }
<!NON_TRIVIAL_BOOLEAN_CONSTANT!>!false<!> -> { }
}
}
@@ -111,4 +111,4 @@ sealed class SClass {
class A : SClass()
class B : SClass()
class C : SClass()
}
}
@@ -212,6 +212,7 @@ enum class LanguageFeature(
ProperTypeInferenceConstraintsProcessing(KOTLIN_1_6, kind = BUG_FIX),
ClassTypeParameterAnnotations(KOTLIN_1_6),
SafeCallsAreAlwaysNullable(KOTLIN_1_6),
ProhibitSimplificationOfNonTrivialConstBooleanExpressions(KOTLIN_1_6),
// Temporarily disabled, see KT-27084/KT-22379
SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX),
@@ -4973,6 +4973,18 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/localObjectInConstructor.kt");
}
@Test
@TestMetadata("loopWithNonTrivialBooleanConst_error.kt")
public void testLoopWithNonTrivialBooleanConst_error() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/loopWithNonTrivialBooleanConst_error.kt");
}
@Test
@TestMetadata("loopWithNonTrivialBooleanConst_warning.kt")
public void testLoopWithNonTrivialBooleanConst_warning() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/loopWithNonTrivialBooleanConst_warning.kt");
}
@Test
@TestMetadata("mainWithWarningOnUnusedParam.kt")
public void testMainWithWarningOnUnusedParam() throws Exception {
@@ -30965,6 +30977,18 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/when/ExhaustiveBooleanNullable.kt");
}
@Test
@TestMetadata("exhaustiveBooleanWhenWithUntrivialConst_error.kt")
public void testExhaustiveBooleanWhenWithUntrivialConst_error() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/exhaustiveBooleanWhenWithUntrivialConst_error.kt");
}
@Test
@TestMetadata("exhaustiveBooleanWhenWithUntrivialConst_warning.kt")
public void testExhaustiveBooleanWhenWithUntrivialConst_warning() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/exhaustiveBooleanWhenWithUntrivialConst_warning.kt");
}
@Test
@TestMetadata("ExhaustiveBreakContinue.kt")
public void testExhaustiveBreakContinue() throws Exception {