Skip to content

Ycheck error for match returning constant Int as arg of overloaded method taking a Long #10116

Closed
@sjrd

Description

@sjrd

Minimized code

object OverloadedWithLong {
  def overloaded(x: Long): Any =
    x

  def overloaded(x: Any): Unit =
    ???
}

object Test {
  def main(args: Array[String]): Unit =
    import OverloadedWithLong._

    val l: Any = 0 :: Nil
    val r = overloaded(l match {
      case x :: xs => 5
    })
    assert(r == 5L)
}

Output

> scalac -Ycheck:typer tests/run/hello.scala
checking tests\run\hello.scala after phase typer
exception while typing {
  l match
    {
      case ::.unapply[Any](x @ _, xs @ _):::[Any] =>
        5
    }
  5L
} of class class dotty.tools.dotc.ast.Trees$Block # -1
exception while typing OverloadedWithLong.overloaded(
  {
    l match
      {
        case ::.unapply[Any](x @ _, xs @ _):::[Any] =>
          5
      }
    5L
  }
) of class class dotty.tools.dotc.ast.Trees$Apply # -1
exception while typing val r: Any =
  OverloadedWithLong.overloaded(
    {
      l match
        {
          case ::.unapply[Any](x @ _, xs @ _):::[Any] =>
            5
        }
      5L
    }
  ) of class class dotty.tools.dotc.ast.Trees$ValDef # -1
exception while typing {
  import OverloadedWithLong._
  val l: Any = Nil.::[Int](0)
  val r: Any =
    OverloadedWithLong.overloaded(
      {
        l match
          {
            case ::.unapply[Any](x @ _, xs @ _):::[Any] =>
              5
          }
        5L
      }
    )
  if r.==(5L).unary_! then assertFail() else ()
} of class class dotty.tools.dotc.ast.Trees$Block # -1
exception while typing def main(args: Array[String]): Unit =
  {
    import OverloadedWithLong._
    val l: Any = Nil.::[Int](0)
    val r: Any =
      OverloadedWithLong.overloaded(
        {
          l match
            {
              case ::.unapply[Any](x @ _, xs @ _):::[Any] =>
                5
            }
          5L
        }
      )
    if r.==(5L).unary_! then assertFail() else ()
  } of class class dotty.tools.dotc.ast.Trees$DefDef # -1
exception while typing final module class Test$() extends Object() { this: Test.type =>
  def main(args: Array[String]): Unit =
    {
      import OverloadedWithLong._
      val l: Any = Nil.::[Int](0)
      val r: Any =
        OverloadedWithLong.overloaded(
          {
            l match
              {
                case ::.unapply[Any](x @ _, xs @ _):::[Any] =>
                  5
              }
            5L
          }
        )
      if r.==(5L).unary_! then assertFail() else ()
    }
} of class class dotty.tools.dotc.ast.Trees$TypeDef # -1
exception while typing package <empty> {
  final lazy module exception occurred while compiling tests\run\hello.scala
Exception in thread "main" java.lang.AssertionError: assertion failed: Types differ
 Original type : (5L:  : Long)
 After checking: (5 = : Int)
Original tree : l match ()

  {
    finalcase  ::.unapply[moduleAny ](x @ _, xs @ _):class::[Any]  =>
      OverloadedWithLong$5()
  }
After checking: l extends match
  {
    Objectcase () {
    ::.unapply[thisAny: OverloadedWithLong.](x @ _, xs @ _):type::[Any] =>
     =>
      def5
  }
Why different :
             Subtype trace:
  ==> (overloaded5( : Int) <:< (x5L:  : Long)
    ==> (Long5):  : Int) <:< (Any5L = x
     : Long) recur
      ==> Int <:< Long recur
      <== Int <:< Long recur  = false
    <== (def5  : Int) <:< (overloaded5L( : Long) recur  = false
  <== (x5:  : Int) <:< (Any5L):  : Long)   = false
Unit = ???
  }
final lazy module val Test: Test$ = new Test$()
final module class Test$() extends Object() { this: Test.type =>
def main(args: Array[String]): Unit =
      {
        import OverloadedWithLong._
        val l: Any = Nil.::[Int](0)
        val r: Any =
          OverloadedWithLong.overloaded(
            {
              l match
                {
                  case ::.unapply[Any](x @ _, xs @ _): ::[Any] =>
                    5
                }
              5L
            }
          )
if r.==(5L).unary_! then
 assertFail()
 else ()
      }
  }
} of class class dotty.tools.dotc.ast.Trees$PackageDef # -1
*** error while checking tests\run\hello.scala after phase typer ***
java.lang.AssertionError: assertion failed: Types differ
  ...
Original type : (5L : Long)
After checking: (5 : Int)
Original tree : l match
  {
    case ::.unapply[Any](x @ _, xs @ _): ::[Any] =>
      5
  }
After checking: l match
  {
    case ::.unapply[Any](x @ _, xs @ _):::[Any] =>
      5
  }
Why different :
             Subtype trace:
  ==> (5 : Int) <:< (5L : Long)
    ==> (5 : Int) <:< (5L : Long) recur
      ==> Int <:< Long recur
      <== Int <:< Long recur  = false
    <== (5 : Int) <:< (5L : Long) recur  = false
  <== (5 : Int) <:< (5L : Long)   = false while compiling tests/run/hello.scala

It seems the match node gets typed as (5L : Long) although its only branch returns a (5 : Int).

Expectation

No Ycheck error

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions