Skip to content

Nested transparent calls *: mangles types #18011

Open
@ncreep

Description

@ncreep

Compiler version

3.3.0

Minimized code

Following #18010 (working around nested transparent calls), I'm adding some summonInline to the mix.
Given the following code:

//> using scala "3.3.0"

import scala.compiletime.*

trait Hidden:
  type Value

object Hidden:
  type Of[A] = Hidden { type Value = A }

  given [A]: Hidden.Of[A] = new Hidden { type Value = A }

class Typed[A]

transparent inline def unhide[T <: Tuple]: Typed[_ <: Tuple] =
  inline erasedValue[T] match
    case _: EmptyTuple => Typed[EmptyTuple]
    case _: (h *: t) =>
      inline unhide[t] match
        case _: Typed[ts] =>
          inline summonInline[h] match
            case _: Hidden.Of[x] =>
              Typed[x *: ts]
              
val x = unhide[(Hidden.Of["a"], Hidden.Of["b"], Hidden.Of["c"])]

Output

The code above fails to compile on the definition of x with:

Found:    Typed[?1.CAP]
Required: Typed[? >: Nothing *: EmptyTuple.type <: Any *: EmptyTuple.type]

where:    ?1 is an unknown value of type scala.runtime.TypeBox[Nothing *: Nothing, Any *: Tuple]

But if I replace the second branch with a seemingly equivalent expression like so:

case _: Hidden.Of[x] =>
  Typed[Prepend[x, ts]]

Where Prepend is defined as:

type Prepend[X, +Y <: Tuple] <: Tuple = X match
  case X => X *: Y

Everything compiles just fine.

(And as per #18010, if I add a random println on that branch it will fully preserve type information.)

Expectation

*: should not cause compilation to fail.

Thanks

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions