I am trying to build a project with 1.4-M1, and ge...
# eap
z
I am trying to build a project with 1.4-M1, and getting a strange type error that I think might be a bug. I will file, but want to get a sanity check first. Here’s a simple reproducer, discussion in thread.
Copy code
data class FunctionHolder<out T : Any>(
  val f: (@UnsafeVariance T) -> Unit
)

fun caller(holder: FunctionHolder<*>) {
  val f: (Any) -> Unit = holder.f
}
So because `FunctionHolder`’s
T
is specified as covariant, I would expect
FunctionHolder<*>
to be equivalent to
FunctionHolder<Any>
, and
FunctionHolder<Any>.f
to be of type
(Any) -> Unit
. And this is indeed the case in 1.3. In 1.4-M1 (with IDE plugin 1.4-M1), it is also what the IDE thinks when doing code completion:
However, the IDE is redlining that expression, and the command-line build fails with the same error, because
holder.f
is apparently
(Nothing) -> Unit
, which I would only expect if
T
was contravariant.
I get the same result whether or not the “Enable new type inference” option is enabled in the IDE plugin.
This seems like a compiler bug to me, does that seem right?
t
JVM target - 1.8?
z
Yes
t
Do you activate
useIR
option in
kotlinOptions
?
z
Nope
t
Problem reproduced in both cases
Do you need test project?
I have one already. With your example.
z
I don’t mind filing a bug, I just wanted to make sure I wasn’t missing something obvious first.
t
Copy code
data class FunctionHolder<out T : Any>(
    val f: (@UnsafeVariance T) -> Unit
)
fun <T: Any> caller(holder: FunctionHolder<T>) {
    val f: (T) -> Unit = holder.f
}
Type parameter for
caller
?
z
Can you elaborate, not sure what you’re asking.
t
holder: FunctionHolder<*>
- not compiled
holder: FunctionHolder<Any>
- compiled
holder: FunctionHolder<T>
- compiled
z
Hm, so either the rules around wildcards changed or that’s where the bug is.
t
message has been deleted
1
z
Oh this also repros for
FunctionHolder<out Any>
, which is what the star-projection actually means.
Also repros for functions defined on
FunctionHolder
, not just properties with function types.
t
I see following problem: If we have
holder: FunctionHolder<*>
it means that it can be
FunctionHolder<String>
It that case error in
val f: (Any) -> Unit = holder.f //holder.f: (String) -> Unit
is valid
z
True, that will result in a runtime cast exception if the parameter to
f
is not actually a
String
, but that error is on the definition of
FunctionHolder
itself and it is suppressed by
@UnsafeVariance
, both in 1.3 and 1.4.
And if this is the expected behavior for some reason, then the warning that “`out` is redundant” is wrong, since the presence of
out
on the parameter to
caller
is the difference between error and no error.