bug
bug copied to clipboard
`java.lang.Boolean.TRUE` doesn't conform to the instance type `java.lang.Boolean.TRUE.type` in function parameters
Scala 2.13.12
Example:
class Key[T] {}
object example {
private val Key: Key[java.lang.Boolean.TRUE.type] = new Key[java.lang.Boolean.TRUE.type]
def putUserData[T](key: Key[T], value: T): Unit = ???
def main(args: Array[String]): Unit = {
//OK: compiles fine
val value: java.lang.Boolean.TRUE.type = java.lang.Boolean.TRUE
val option: Option[java.lang.Boolean.TRUE.type] = Option(java.lang.Boolean.TRUE)
//Error: found: Boolean, required: Boolean.TRUE.type
putUserData(Key, java.lang.Boolean.TRUE)
}
}
The code compiles with error at line 14
type mismatch;
found : Boolean
required: Boolean.TRUE.type
putUserData(Key, java.lang.Boolean.TRUE)
Note that it compiles fine in Scala 3.3.1
java.lang.Boolean.TRUE might be used just as some marker for some API.
In Scala Plugin we have several places where it is actual, though not critical
Scala 2 types the arg as java.lang.Boolean.
[log typer] infer method inst example.this.putUserData[T], tparams = List(type T), args = List(<empty>.this.Key[Boolean.TRUE.type], lang.this.Boolean), pt = scala.this.Unit, lobounds = List(scala.this.Nothing), parambounds = List()
so it gets T correct
example.this.putUserData[Boolean.TRUE.type](example.this.Key, java.lang.Boolean.<TRUE: error>)
The example works in Scala 2 if
class Key[+T]
Dotty is more patient. Presumably it's not widening the arg. (I can't tell by looking.)
private[this] val Key: Key[java.lang.Boolean.TRUE.type] = new Key[java.lang.Boolean.TRUE.type]()
def putUserData[T >: Nothing <: Any](key: Key[T], value: T): Unit = ()
def main(args: Array[String]): Unit =
{
val value: java.lang.Boolean.TRUE.type = java.lang.Boolean.TRUE
val option: Option[java.lang.Boolean.TRUE.type] = Option.apply[(Boolean.TRUE : Boolean)](java.lang.Boolean.TRUE)
example.putUserData[(Boolean.TRUE : Boolean)](example.Key, java.lang.Boolean.TRUE)
}
The example works in Scala 2 if class Key[+T]
Unfortunately, the original Key definition in our case code is in a Java library (IntelliJ IDEA SDK)
(Perhaps this is obvious and/or pedantic, but for the record: this is a type inference issue (not conformance), and the workaround is to explicitly supply the type parameter.)
This may be a pedantic nitpick, but
The code compiles with error at line 14
should say that it does not compile.
Also pedantically, it infers the correct type argument (the singleton) but then "widens" the type of the argument written by the user. So although inference is implicated, I would characterize this as a bug and not a limitation.
Literal works:
putUserData(null.asInstanceOf[Key[42]], 42) // or true
Too outré.
putUserData(Key, java.lang.Boolean.TRUE: java.lang.Boolean.TRUE.type) // or any x.type
Either of these work:
putUserData(Key, value) // value is the singleton type as shown above
putUserData[java.lang.Boolean.TRUE.type](Key, java.lang.Boolean.TRUE)