Support type inference for self type materialization calls

This commit is contained in:
Victor Petukhov
2021-06-30 16:21:58 +03:00
parent 44cf4be1e5
commit 51c5a54e31
21 changed files with 183 additions and 89 deletions
@@ -18,12 +18,4 @@ fun <K : Builder<K>> testTypeParam(builder: Builder<K>) {
builder
.test()
.foo()
}
interface BodySpec<B, S : BodySpec<B, S>> {
fun <T : S> isEqualTo(expected: B): T
}
fun test(b: BodySpec<String, *>) {
b.isEqualTo("")
}
@@ -1,15 +1,24 @@
fun test() {
WriterAppender.newBuilder()
<!DEBUG_INFO_EXPRESSION_TYPE("WriterAppender.Builder1<*>")!>WriterAppender.newBuilder()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("WriterAppender.Builder1<out WriterAppender.Builder1<*>>")!>WriterAppender.Builder1()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("{Builder1<*> & Builder2<*>}")!>WriterAppender.intersectTwoSelfTypes()<!>
}
object WriterAppender {
class Builder<B : Builder<B>> {
interface Builder2<K : Builder2<K>>
class Builder1<B : Builder1<B>> {
fun asBuilder(): B {
return this as B
return this <!UNCHECKED_CAST!>as B<!>
}
}
fun <B : Builder<B>> newBuilder(): B {
return Builder<B>().asBuilder()
fun <B : Builder1<B>> newBuilder(): B {
return Builder1<B>().asBuilder()
}
fun <B> intersectTwoSelfTypes(): B where B : Builder1<B>, B: Builder2<B> {
return Builder1<B>().asBuilder()
}
}
@@ -1,15 +1,24 @@
fun test() {
WriterAppender.<!TYPE_MISMATCH!>newBuilder<!>()
<!DEBUG_INFO_EXPRESSION_TYPE("WriterAppender.Builder1<*>")!>WriterAppender.newBuilder()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("WriterAppender.Builder1<out WriterAppender.Builder1<*>>")!>WriterAppender.Builder1()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("{Builder1<*> & Builder2<*>}")!>WriterAppender.intersectTwoSelfTypes()<!>
}
object WriterAppender {
class Builder<B : Builder<B>> {
interface Builder2<K : Builder2<K>>
class Builder1<B : Builder1<B>> {
fun asBuilder(): B {
return this <!UNCHECKED_CAST!>as B<!>
}
}
fun <B : Builder<B>> newBuilder(): B {
return Builder<B>().asBuilder()
fun <B : Builder1<B>> newBuilder(): B {
return Builder1<B>().asBuilder()
}
fun <B> intersectTwoSelfTypes(): B where B : Builder1<B>, B: Builder2<B> {
return Builder1<B>().asBuilder()
}
}
@@ -6,14 +6,21 @@ public object WriterAppender {
private constructor WriterAppender()
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 final fun </*0*/ B : WriterAppender.Builder<B>> newBuilder(): B
public final fun </*0*/ B : WriterAppender.Builder1<B>> intersectTwoSelfTypes(): B where B : WriterAppender.Builder2<B>
public final fun </*0*/ B : WriterAppender.Builder1<B>> newBuilder(): B
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final class Builder</*0*/ B : WriterAppender.Builder<B>> {
public constructor Builder</*0*/ B : WriterAppender.Builder<B>>()
public final class Builder1</*0*/ B : WriterAppender.Builder1<B>> {
public constructor Builder1</*0*/ B : WriterAppender.Builder1<B>>()
public final fun asBuilder(): B
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 Builder2</*0*/ K : WriterAppender.Builder2<K>> {
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
}
}