Skip to content

Type inference for dependent type class breaks (regression from Scala 2) #10929

Closed
@LPTK

Description

@LPTK

Minimized code

infix abstract class TupleOf[T, +A]:
  type Mapped[+A] <: Tuple
  def map[B](x: T)(f: A => B): Mapped[B]

object TupleOf:
  
  given TupleOf[EmptyTuple, Nothing] with
    type Mapped[+A] = EmptyTuple
    def map[B](x: EmptyTuple)(f: Nothing => B): Mapped[B] = x
  
  given [A, Rest <: Tuple](using tup: Rest TupleOf A): TupleOf[A *: Rest, A] with
    type Mapped[+A] = A *: tup.Mapped[A]
    def map[B](x: A *: Rest)(f: A => B): Mapped[B] =
      (f(x.head) *: tup.map(x.tail)(f))

def foo[T](xs: T)(using tup: T TupleOf Int): tup.Mapped[Int] = tup.map(xs)(_ + 1)

@main def test =
  foo(EmptyTuple): EmptyTuple // ok
  foo(1 *: EmptyTuple): Int *: EmptyTuple // nope

https://scastie.scala-lang.org/TQKBd1mmR6qygyuY0vMSMg

It works in Scala 2 : https://scastie.scala-lang.org/XTg2Thj5QYSyEzSNL5xUpQ

Output

Found:    ?1.Mapped[Int]
Required: Int *: EmptyTuple
where:    ?1 is an unknown value of type TupleOf.given_TupleOf_A_A[Int, EmptyTuple.type]

Expectation

Compiles. The Mapped type of any TupleOf.given_TupleOf_A_A[Int, EmptyTuple.type] value is [A] =>> A *: EmptyTuple. So ?1.Mapped[Int] should be reduced to Int *: EmptyTuple.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions