Correcting rewrite type info after compete call.
#KT-10934 Fixed #KT-10896 Fixed
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
//KT-10934 compiler throws UninferredParameterTypeConstructor in when block that covers all types
|
||||
|
||||
class Parser<TInput, TValue>(val f: (TInput) -> Result<TInput, TValue>) {
|
||||
|
||||
operator fun invoke(input: TInput): Result<TInput, TValue> = f(input)
|
||||
|
||||
fun <TIntermediate, TValue2> mapJoin(
|
||||
selector: (TValue) -> Parser<TInput, TIntermediate>,
|
||||
projector: (TValue, TIntermediate) -> TValue2
|
||||
): Parser<TInput, TValue2> {
|
||||
return Parser({ input ->
|
||||
val res = this(input)
|
||||
when (res) {
|
||||
is Result.ParseError -> Result.ParseError(res.productionLabel, res.child, res.rest)
|
||||
is Result.Value -> {
|
||||
val v = res.value
|
||||
val res2 = selector(v)(res.rest)
|
||||
when (res2) {
|
||||
is Result.ParseError -> Result.ParseError(res2.productionLabel, res2.child, res2.rest)
|
||||
is Result.Value -> Result.Value(projector(v, res2.value), res2.rest)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/** A parser can return one of two Results */
|
||||
sealed class Result<TInput, TValue> {
|
||||
|
||||
class Value<TInput, TValue>(val value: TValue, val rest: TInput) : Result<TInput, TValue>() {}
|
||||
|
||||
class ParseError<TInput, TValue>(val productionLabel: String,
|
||||
val child: ParseError<TInput, *>?,
|
||||
val rest: TInput) : Result<TInput, TValue>() {}
|
||||
}
|
||||
|
||||
fun box() = "OK"
|
||||
@@ -0,0 +1,26 @@
|
||||
interface Option<out T> {
|
||||
val s: String
|
||||
}
|
||||
class Some<T>(override val s: String) : Option<T>
|
||||
class None(override val s: String = "None") : Option<Int>
|
||||
|
||||
fun whenTest(a: Int): Option<Any> = when (a) {
|
||||
239 -> {
|
||||
if (a == 239) Some("239") else None()
|
||||
}
|
||||
else -> if (a != 239) Some("$a") else None()
|
||||
}
|
||||
|
||||
fun ifTest(a: Int): Option<Any> = if (a == 239) {
|
||||
if (a == 239) Some("239") else None()
|
||||
} else if (a != 239) Some("$a") else None()
|
||||
|
||||
fun box(): String {
|
||||
if (whenTest(2).s != "2") return "Fail 1"
|
||||
if (whenTest(239).s != "239") return "Fail 2"
|
||||
|
||||
if (ifTest(2).s != "2") return "Fail 3"
|
||||
if (ifTest(239).s != "239") return "Fail 4"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// !CHECK_TYPE
|
||||
// See also KT-10896: Wrong inference of if / else result type
|
||||
|
||||
interface Option<T>
|
||||
class Some<T> : Option<T>
|
||||
class None<T> : Option<T>
|
||||
|
||||
fun <T> bind(r: Option<T>): Option<T> {
|
||||
return if (r is Some) {
|
||||
// Ideally we should infer Option<T> here (see KT-10896)
|
||||
(<!TYPE_INFERENCE_FAILED_ON_SPECIAL_CONSTRUCT!>if<!> (true) <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>None()<!> else <!DEBUG_INFO_SMARTCAST!>r<!>) checkType { <!TYPE_MISMATCH!>_<!><Option<T>>() }
|
||||
// Works correctly
|
||||
if (true) None() else r
|
||||
}
|
||||
else r
|
||||
}
|
||||
|
||||
fun <T> bind2(r: Option<T>): Option<T> {
|
||||
return if (r is Some) {
|
||||
// Works correctly
|
||||
if (true) None<T>() else r
|
||||
}
|
||||
else r
|
||||
}
|
||||
|
||||
fun <T, R> bind3(r: Option<T>): Option<T> {
|
||||
return if (r is Some) {
|
||||
// Diagnoses an error correctly
|
||||
if (true) <!TYPE_MISMATCH!>None<R>()<!> else r
|
||||
}
|
||||
else r
|
||||
}
|
||||
|
||||
fun <T> bindWhen(r: Option<T>): Option<T> {
|
||||
return when (r) {
|
||||
is Some -> {
|
||||
// Works correctly
|
||||
if (true) None() else r
|
||||
}
|
||||
else -> r
|
||||
}
|
||||
}
|
||||
|
||||
interface SimpleOption
|
||||
class SimpleSome : SimpleOption
|
||||
class SimpleNone : SimpleOption
|
||||
|
||||
fun bindNoGeneric(r: SimpleOption): SimpleOption {
|
||||
return if (r is SimpleSome) {
|
||||
(if (true) SimpleNone() else r) checkType { _<SimpleOption>() }
|
||||
if (true) SimpleNone() else r
|
||||
}
|
||||
else r
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ T> bind(/*0*/ r: Option<T>): Option<T>
|
||||
public fun </*0*/ T> bind2(/*0*/ r: Option<T>): Option<T>
|
||||
public fun </*0*/ T, /*1*/ R> bind3(/*0*/ r: Option<T>): Option<T>
|
||||
public fun bindNoGeneric(/*0*/ r: SimpleOption): SimpleOption
|
||||
public fun </*0*/ T> bindWhen(/*0*/ r: Option<T>): Option<T>
|
||||
|
||||
public final class None</*0*/ T> : Option<T> {
|
||||
public constructor None</*0*/ T>()
|
||||
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
|
||||
}
|
||||
|
||||
public interface Option</*0*/ T> {
|
||||
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
|
||||
}
|
||||
|
||||
public final class SimpleNone : SimpleOption {
|
||||
public constructor SimpleNone()
|
||||
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
|
||||
}
|
||||
|
||||
public interface SimpleOption {
|
||||
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
|
||||
}
|
||||
|
||||
public final class SimpleSome : SimpleOption {
|
||||
public constructor SimpleSome()
|
||||
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
|
||||
}
|
||||
|
||||
public final class Some</*0*/ T> : Option<T> {
|
||||
public constructor Some</*0*/ T>()
|
||||
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