Skip to content

NamedTuple selection on the result of NamedTuple.Concat doesn't work #20427

Closed
@smarter

Description

@smarter

Compiler version

3.5.0-RC1-bin-20240516-c608177-NIGHTLY

Minimized code

import scala.language.experimental.namedTuples

object Test:
  type NT = NamedTuple.Concat[(hi: Int), (bla: String)]
  def foo(x: NT) =
    x.hi // error
    val y: (hi: Int, bla: String) = x
    y.hi // ok

Output

[error] ./try/nt.scala:6:5
[error] Found:    (x$proxy1 : (x : Test.NT) &
[error]   $proxy1.NamedTuple[
[error]     Tuple.Concat[
[error]       NamedTupleDecomposition.Names[
[error]         $proxy1.NamedTuple[Tuple1[("hi" : String)], Tuple1[Int]]],
[error]       NamedTupleDecomposition.Names[
[error]         $proxy1.NamedTuple[Tuple1[("bla" : String)], Tuple1[String]]]
[error]     ],
[error]     Tuple.Concat[
[error]       NamedTupleDecomposition.DropNames[
[error]         $proxy1.NamedTuple[Tuple1[("hi" : String)], Tuple1[Int]]],
[error]       NamedTupleDecomposition.DropNames[
[error]         $proxy1.NamedTuple[Tuple1[("bla" : String)], Tuple1[String]]]
[error]     ]
[error]   ]
[error] )
[error] Required: (Int, String)
[error]     x.hi // error
[error]     ^

Expectation

A valid selection.

More details

The selection desugars into something equivalent to:

NamedTuple.apply[("hi", "bla"), (Int, String)](x)(0)

With -Xprint:inlining I get:

        val $proxy1:

            NamedTuple.type{
              type AnyNamedTuple = Any;
                type NamedTuple[N <: Tuple,V <: Tuple] = V
            }

         =
          NamedTuple.$asInstanceOf[

              NamedTuple.type{
                type AnyNamedTuple = Any;
                  type NamedTuple[N <: Tuple,V <: Tuple] = V
              }

          ]
        val NamedTuple$_this:

            ($proxy1 :
              NamedTuple.type{
                type AnyNamedTuple = Any;
                  type NamedTuple[N <: Tuple,V <: Tuple] = V
              }
            )

         = $proxy1
        {
          val $scrutinee1: <error unspecified error> =
            NamedTuple$_this.toTuple[(("hi" : String), ("bla" : String)),
              (Int, String)](x$proxy1)
          val tup: <error unspecified error> = $scrutinee1
          tup.apply[(Int, String) & NonEmptyTuple](0).asInstanceOf[
            Tuple.Elem[(Int, String), 0.type]]
  • I'm not sure why we end up creating proxies for the top-level object NamedTuple here
  • The call to toTuple refers to an argument x$proxy1 but the pretty-printed tree doesn't contain any definition with that name.
  • Manually calling toTuple on my concatenated named tuple works.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions