Skip to content

Union type reduction fails in Tuple(A, A).toList #24214

@yurique

Description

@yurique

Compiler version

  • 3.8.0-RC1-bin-20251007-71fcd1a-NIGHTLY
  • 3.7.4-RC
  • 3.7.3
  • 3.7.2
  • 3.6.4
  • 3.5.2

This does NOT reproduce in 3.3.6 LTS.

Minimized code

Minimization from Aly in Discord:

//> using scala 3.8.0-RC1-bin-20251007-71fcd1a-NIGHTLY
def foo(x: (String, String)): List[String] = x.toList

(https://scastie.scala-lang.org/i0Zz6XF1RECi9EUzjklVFg)

Output

[error] ./tuple.sc:2:46
[error] Found:    List[Tuple.Union[(x : (String, String))]]
[error] Required: List[String]
[error]
[error] Note: a match type could not be fully reduced:
[error]
[error]   trying to reduce  Tuple.Union[(x : (String, String))]
[error]   trying to reduce  Tuple.Fold[(x : (String, String)), Nothing, [x, y] =>> x | y]
[error]   failed since selector (x : (String, String))
[error]   does not uniquely determine parameters h, t in
[error]     case h *: t => h | Tuple.Fold[t, Nothing, [x, y] =>> x | y]
[error]   The computed bounds for the parameters are:
[error]     h <: String
[error]     t <: String *: EmptyTuple.type
[error] def foo(x: (String, String)): List[String] = x.toList
[error]                                              ^^^^^^^^

Initially, we discovered this issue when seeing different behaviors with and without case

  • .map { case x => x.toList } - compiles
  • .map { x => x.toList } - does not compile
//> using scala 3.8.0-RC1-bin-20251007-71fcd1a-NIGHTLY

sealed trait Container[+A] { def map[B](fn: A => B) = ??? }

val tup: Container[(String, String)] = ???

// compiles
tup.map { case x => x.toList }

// does not compile
tup.map { x => x.toList }

(https://scastie.scala-lang.org/ISWA7siCTmqjJ9D2dUF2WQ)

Output:

[error] ./tuple2.sc:11:16
[error] Found:    List[Tuple.Union[(x : (String, String))]]
[error] Required: List[String]
[error]
[error] Note: a match type could not be fully reduced:
[error]
[error]   trying to reduce  Tuple.Union[(x : (String, String))]
[error]   trying to reduce  Tuple.Fold[(x : (String, String)), Nothing, [x, y] =>> x | y]
[error]   failed since selector (x : (String, String))
[error]   does not uniquely determine parameters h, t in
[error]     case h *: t => h | Tuple.Fold[t, Nothing, [x, y] =>> x | y]
[error]   The computed bounds for the parameters are:
[error]     h <: String
[error]     t <: String *: EmptyTuple.type
[error] tup.map { x => x.toList }
[error]                ^^^^^^^^

Expectation

The code should compile.

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