Skip to content

asInstanceOf inlining causes the difference in result #13103

Closed as not planned
Closed as not planned
@REASY

Description

@REASY

The code below generates bytecode that makes asOptBoolean1 and asOptBoolean2 to not produce the same result in case if null is provided. asOptBoolean1 will never return None.

class TestRow(values: Array[Any]) {
  def get(i: Int): Any = values(i)

  def getAs[T](i: Int): T = get(i).asInstanceOf[T]
}

object Main {
  private def asOptBoolean1(r: TestRow, index: Int): Option[Boolean] = {
    val bool = r.getAs[Boolean](index)
    Option(bool)
  }

  private def asOptBoolean2(r: TestRow, index: Int): Option[Boolean] = {
    Option(r.getAs[Boolean](index))
  }

  def main(args: Array[String]): Unit = {
    val row    = new TestRow(Array(null, true, false))
    println(s"asOptBoolean1 at 0: ${asOptBoolean1(row, 0)}")
    println(s"asOptBoolean1 at 1: ${asOptBoolean1(row, 1)}")

    println(s"asOptBoolean2 at 0: ${asOptBoolean2(row, 0)}")
    println(s"asOptBoolean2 at 1: ${asOptBoolean2(row, 1)}")
  }
}

It produces the following output

asOptBoolean1 at 0: Some(false)
asOptBoolean1 at 1: Some(true)
asOptBoolean2 at 0: None
asOptBoolean2 at 1: Some(true)

The generated bytecode https://godbolt.org/z/sGhz9WYh9, as you can see there is boxing/unboxing in asOptBoolean1 that causes null to become false as primitive

Image

I use Scala 2.13.15

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions