Implementation of exhaustive whens in control flow analysis.
Now control flow analyzer knows when is exhaustive. If despite of this all conditions are accidentally false, jump to error is generated. A set of tests (diagnostic, control flow). #KT-5113 Fixed. #KT-6046 Fixed. #KT-1882 Fixed.
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
enum class Direction {
|
||||
NORTH, SOUTH, WEST, EAST
|
||||
}
|
||||
|
||||
fun foo(dir: Direction): Int {
|
||||
val res: Int
|
||||
// See KT-6046: res is always initialized
|
||||
when (dir) {
|
||||
Direction.NORTH -> res = 1
|
||||
Direction.SOUTH -> res = 2
|
||||
Direction.WEST -> res = 3
|
||||
Direction.EAST -> res = 4
|
||||
}
|
||||
return res
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package
|
||||
|
||||
internal fun foo(/*0*/ dir: Direction): kotlin.Int
|
||||
|
||||
internal final enum class Direction : kotlin.Enum<Direction> {
|
||||
public enum entry NORTH : Direction {
|
||||
private constructor NORTH()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Direction): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry SOUTH : Direction {
|
||||
private constructor SOUTH()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Direction): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry WEST : Direction {
|
||||
private constructor WEST()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Direction): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry EAST : Direction {
|
||||
private constructor EAST()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Direction): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
private constructor Direction()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Direction): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Direction
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<Direction>
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
enum class MyEnum {
|
||||
A, B
|
||||
}
|
||||
|
||||
fun foo(x: MyEnum?): Int {
|
||||
val y: Int
|
||||
// See KT-6046: y is always initialized
|
||||
when (x) {
|
||||
MyEnum.A -> y = 1
|
||||
MyEnum.B -> y = 2
|
||||
null -> y = 0
|
||||
}
|
||||
return y
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package
|
||||
|
||||
internal fun foo(/*0*/ x: MyEnum?): kotlin.Int
|
||||
|
||||
internal final enum class MyEnum : kotlin.Enum<MyEnum> {
|
||||
public enum entry A : MyEnum {
|
||||
private constructor A()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry B : MyEnum {
|
||||
private constructor B()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
private constructor MyEnum()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): MyEnum
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<MyEnum>
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
enum class Direction {
|
||||
NORTH, SOUTH, WEST, EAST
|
||||
}
|
||||
|
||||
fun foo(dir: Direction): Int {
|
||||
when (dir) {
|
||||
Direction.NORTH -> return 1
|
||||
Direction.SOUTH -> return 2
|
||||
Direction.WEST -> return 3
|
||||
Direction.EAST -> return 4
|
||||
}
|
||||
// See KT-1882: no return is needed at the end
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package
|
||||
|
||||
internal fun foo(/*0*/ dir: Direction): kotlin.Int
|
||||
|
||||
internal final enum class Direction : kotlin.Enum<Direction> {
|
||||
public enum entry NORTH : Direction {
|
||||
private constructor NORTH()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Direction): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry SOUTH : Direction {
|
||||
private constructor SOUTH()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Direction): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry WEST : Direction {
|
||||
private constructor WEST()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Direction): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry EAST : Direction {
|
||||
private constructor EAST()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Direction): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
private constructor Direction()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Direction): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Direction
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<Direction>
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// See KT-5113
|
||||
enum class E {
|
||||
A,
|
||||
B
|
||||
}
|
||||
|
||||
class Outer(e: E) {
|
||||
private val prop: Int
|
||||
init {
|
||||
when(e ) {
|
||||
// When is exhaustive, property is always initialized
|
||||
E.A -> prop = 1
|
||||
E.B -> prop = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package
|
||||
|
||||
internal final enum class E : kotlin.Enum<E> {
|
||||
public enum entry A : E {
|
||||
private constructor A()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: E): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry B : E {
|
||||
private constructor B()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: E): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
private constructor E()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: E): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): E
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<E>
|
||||
}
|
||||
|
||||
internal final class Outer {
|
||||
public constructor Outer(/*0*/ e: E)
|
||||
private final val prop: kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
Reference in New Issue
Block a user