bug icon indicating copy to clipboard operation
bug copied to clipboard

`java.lang.Boolean.TRUE` doesn't conform to the instance type `java.lang.Boolean.TRUE.type` in function parameters

Open unkarjedy opened this issue 2 years ago • 5 comments

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

unkarjedy avatar Nov 07 '23 14:11 unkarjedy

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

unkarjedy avatar Nov 07 '23 15:11 unkarjedy

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)
      }

som-snytt avatar Nov 07 '23 18:11 som-snytt

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)

unkarjedy avatar Nov 08 '23 09:11 unkarjedy

(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.)

SethTisue avatar Jan 26 '24 22:01 SethTisue

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)

som-snytt avatar Jan 27 '24 01:01 som-snytt