Skip to content

Inference fails to properly use equality evidence #21509

Open
@kyouko-taiga

Description

@kyouko-taiga

Compiler version

3.5.0

Minimized code

Consider the following program:

trait Iter[Self]:
  type Elem
  extension (self: Self) def next: Option[(Elem, Self)]

given Iter[Int] with
  type Elem = Byte
  extension (self: Int) def next: Option[(Byte, Int)] =
    val b = self & 0xff
    if b != 0 then Some((b.toByte, self >> 8)) else None

final case class Pair[T, U](first: T, second: U)

extension[T, U](using Iter[T], T =:= U)(self: Pair[T, U])
  def hasEqualParts: Boolean =
    self.first.next match
      case None => self.second.next == None
      case Some((x, xs)) =>
        self.second.next match
          case None => false
          case Some((y, ys)) =>
            if x == y then Pair(xs, ys).hasEqualParts else false

Two errors are reported about next not being a member of U in the expressions self.second.next, revealing that the compiler failed to find next as an extension method of U, which should hold under the assumption that T is equal to U.

Perhaps more surprisingly, the following changes also result in a type error (changed lines are highlighted with //!):

extension[T, U](using Iter[T], T =:= U)(self: Pair[T, U])
  def hasEqualParts: Boolean =
    self.first.next match
      case None => self.first.next == None // !
      case Some((x, xs)) =>
        self.first.next match // !
          case None => false
          case Some((y, ys)) =>
            if x == y then Pair(xs, ys).hasEqualParts else false

The implementation is now incorrect but it should type check. Yet, the compiler complains in the last line about hasEqualParts not being a member of Pair[T, T], which is clearly not true. Note that the error disappear if:

  • we remove the needless equality evidence T =:= U
  • we take self as an instance of Pair[T, T]

Output

In the first example:

value next is not a member of U
value next is not a member of U

In the second example:

value hasEqualParts is not a member of Pair[T, T].
An extension method was tried, but could not be fully constructed:

    hasEqualParts[T, U](x$1, x$2)(Pair.apply[T, T](xs, ys))

    failed with:

        Found:    Pair[T, T]
        Required: Pair[T, U]

Expectation

Both version of hasEqualParts should type check.

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