Skip to content

Extension methods with recursive implicit resolution do not work #7056

Closed
@anatoliykmetyuk

Description

@anatoliykmetyuk
import Tuple.{ Head, Tail }

trait Idnt[T1 <: Tuple] {
  type Res <: Tuple
  extension (t1: T1) def idnt: Res
}

type Aux[T1 <: Tuple, Res0] = Idnt[T1] { type Res = Res0 }

given [T1 <: NonEmptyTuple, TZ <: Tuple](using Aux[Tail[T1], TZ]) : Aux[T1, Head[T1] *: TZ] = new Idnt[T1] {
  type Res = Head[T1] *: TZ
  extension (t1: T1) def idnt: Res = t1.head *: t1.tail.idnt
}

given Aux[Unit, Unit] = new Idnt[Unit] {
  type Res = Unit
  extension (t1: Unit) def idnt: Unit = ()
}

val x: (1, 2, 3) = (1, 2, 3)
val z: (1, 2, 3) = x.idnt

Says:

-- [E008] Member Not Found Error: ../pg/Main.scala:23:21 -----------------------
23 |val z: (1, 2, 3) = x.idnt
   |                   ^^^^^^
   |value idnt is not a member of (Int(1), Int(2), Int(3)) - did you mean x._1?.
   |An extension method was tried, but could not be fully constructed:
   |
   |    Main$package.Aux_T1_Head_given[(Int(1), Int(2), Int(3)), Tuple](
   |      Main$package.Aux_T1_Head_given[T1, TZ]
   |    ).idnt()
one error found

But:

import Tuple.{ Head, Tail }

trait Idnt[T1 <: Tuple] {
  type Res <: Tuple
  def (t1: T1) idnt: Res
}

type Aux[T1 <: Tuple, Res0] = Idnt[T1] { type Res = Res0 }

given [T1 <: NonEmptyTuple] as Aux[T1, Head[T1] *: Tail[T1]]
  = new Idnt[T1] {
  type Res = Head[T1] *: Tail[T1]
  def (t1: T1) idnt: Res = t1.head *: t1.tail
}

given as Aux[Unit, Unit] = new Idnt[Unit] {
  type Res = Unit
  def (t1: Unit) idnt: Unit = ()
}

val x: (1, 2, 3) = (1, 2, 3)
val z: (1, 2, 3) = x.idnt

Works. My gut feeling tells me it is related to #7049 and #7050.

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