Marc Knaup
07/30/2020, 12:05 PM<*>
when casting to the generic GraphEnumDefinition
? Or a bug? 😄
It’s inferred correctly.Marc Knaup
07/30/2020, 12:07 PMclass GraphEnumDefinition<Value : Enum<Value>>
<*>
would mean <Enum<*>>
but it’s inferred to <Any>
.Victor Petukhov
08/01/2020, 8:35 AMtype.raptorTypeDefinition
has? It would be ideal if you shared an isolated reproducing example.
I have an error about missed type argument with any left side of the as
operator.Marc Knaup
08/01/2020, 11:34 AMfun main(foo: Base<*>) {
val bar = foo as Derived
}
sealed class Base<T>
class Derived<T> : Base<T>()
Victor Petukhov
08/01/2020, 2:44 PMMarc Knaup
08/01/2020, 2:47 PMT: Enum<T>
In that case all functions/properties of Enum
were missing because *
was not inferred to Enum<*>
Victor Petukhov
08/01/2020, 3:25 PMfun main(foo: Base<*>) {
if (foo is Derived) {
foo.x // Any?
}
if (foo is Derived<*>) {
foo.x // Foo
}
}
interface Base<T>
interface Foo
class Derived<T : Foo>(val x: T): Base<T>
It’s intended behaviour as the bare types implies substitution of a type argument of the super type (including its declaration site bounds) into casting/checking type. In given case, the super type is Base
, it doesn’t have Foo
upper bound on its type parameter so we get Any?
instead of Foo
.
One more example to clarify:
fun main(foo: Base<Bar>) {
if (foo is Derived) {
foo.x // Bar
}
if (foo is Derived<*>) {
foo.x // Foo
}
}
interface Base<T>
interface Foo
interface Bar
class Derived<T : Foo>(val x: T): Base<T>
Another side is that we can detect cases when type argument bounds of Derived
and Base
is incompatible, and report an error. You can create an issue about it in YouTrack if you want, and we’ll consider making such error in the future.Marc Knaup
08/01/2020, 3:31 PM<*>
as it’s easy to miss, the result is quite unexpected and the resulting errors downstream are confusing.
Also, inference shows both as Derived<*>
but with different meaning (in my case).Marc Knaup
08/01/2020, 3:33 PMVictor Petukhov
08/01/2020, 3:39 PMbar1
and bar2
different upper bounds are hidden behind *
(in my initial example, they would be Any?
and Foo
i.e. Derived<out Any?>
and Derived<out Foo>
for producers). I agree that there is implicit behavior here. Anyway we’ll try to do something with it, at least an inspection in IDE.Marc Knaup
08/01/2020, 3:47 PM