Skip to content

Regression on Tuple.Union when using Tuple.toList #16583

Closed
@hmf

Description

@hmf

Compiler version

Worked on 3.2.1
Fails on 3.2.2-RC2

Minimized code

  val ll0: Tuple3["one", "two", "three"] = constValueTuple[("one", "two", "three")]
  val ll1 = constValueTuple[("one", "two", "three")].toList
  val ll3: List["one" | ("two" | ("three" | Nothing))] = constValueTuple[("one", "two", "three")].toList
  val ll4: List["one" | ("two" | "three")] = constValueTuple[("one", "two", "three")].toList

  inline def labels[Labels <: Tuple](using ev: Tuple.Union[Labels] <:< String): List[String] = 
    val tmp = constValueTuple[Labels].toList
    ev.substituteCo( tmp )

  val strings = labels[("one", "two", "three")]
  // returns List(one, two, three)
  println(strings.mkString("<", ", ", ">"))

Output

error] -- [E007] Type Mismatch Error: /home/hmf/VSCodeProjects/sploty/meta/src/data/Meta1.scala:46:53 
[error] 46 |  val ll1 = constValueTuple[("one", "two", "three")].toList
[error]    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[error]    |Found:    List[
[error]    |  Tuple.Union[(?1 : (("one" : String), ("two" : String), ("three" : String)))]
[error]    |]
[error]    |Required: List[("one" : String) | (("two" : String) | (("three" : String) | Nothing))]
[error]    |
[error]    |where:    ?1 is an unknown value of type (("one" : String), ("two" : String), ("three" : String))
[error]    |----------------------------------------------------------------------------
[error]    | Explanation (enabled by `-explain`)
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |
[error]    | Tree: scala.compiletime.constValueTuple[Tuple3["one".type, "two".type, "three".type]].
[error]    |   toList
[error]    | I tried to show that
[error]    |   List[
[error]    |   Tuple.Union[(?1 : (("one" : String), ("two" : String), ("three" : String)))]
[error]    | ]
[error]    | conforms to
[error]    |   List[("one" : String) | (("two" : String) | (("three" : String) | Nothing))]
[error]    | but the comparison trace ended with `false`:
[error]    |
[error]    |   ==> List[   Tuple.Union[(?1 : (("one" : String), ("two" : String), ("three" : String)))] ]  <:  List[("one" : String) | (("two" : String) | (("three" : String) | Nothing))]
[error]    |     ==> Tuple.Union[(?1 : (("one" : String), ("two" : String), ("three" : String)))]  <:  ("one" : String) | (("two" : String) | (("three" : String) | Nothing))
[error]    |       ==> Tuple.Union[(?1 : (("one" : String), ("two" : String), ("three" : String)))]  <:  Nothing
[error]    |         ==> lub(Nothing, ("one" : String), canConstrain=false, isSoft=true)
[error]    |         <== lub(Nothing, ("one" : String), canConstrain=false, isSoft=true) = ("one" : String)
[error]    |         ==> lub(Nothing, (("two" : String), ("three" : String)), canConstrain=false, isSoft=true)
[error]    |         <== lub(Nothing, (("two" : String), ("three" : String)), canConstrain=false, isSoft=true) = (("two" : String), ("three" : String))
[error]    |         ==> lub(Nothing, ("two" : String), canConstrain=false, isSoft=true)
[error]    |         <== lub(Nothing, ("two" : String), canConstrain=false, isSoft=true) = ("two" : String)
[error]    |         ==> lub(Nothing, ("three" : String) *: EmptyTuple.type, canConstrain=false, isSoft=true)
[error]    |         <== lub(Nothing, ("three" : String) *: EmptyTuple.type, canConstrain=false, isSoft=true) = ("three" : String) *: EmptyTuple.type
[error]    |         ==> lub(Nothing, ("three" : String), canConstrain=false, isSoft=true)
[error]    |         <== lub(Nothing, ("three" : String), canConstrain=false, isSoft=true) = ("three" : String)
[error]    |         ==> lub(Nothing, EmptyTuple.type, canConstrain=false, isSoft=true)
[error]    |         <== lub(Nothing, EmptyTuple.type, canConstrain=false, isSoft=true) = EmptyTuple.type
[error]    |         ==> Nothing  <:  ("three" : String) in frozen constraint
[error]    |         <== Nothing  <:  ("three" : String) in frozen constraint = true
[error]    |         ==> lub(<notype>, <notype>, canConstrain=false, isSoft=true)
[error]    |         <== lub(<notype>, <notype>, canConstrain=false, isSoft=true) = <notype>
[error]    |         ==> lub(<notype>, <notype>, canConstrain=false, isSoft=true)
[error]    |         <== lub(<notype>, <notype>, canConstrain=false, isSoft=true) = <notype>
[error]    |         ==> lub(Nothing, ("one" : String), canConstrain=false, isSoft=true)
[error]    |         <== lub(Nothing, ("one" : String), canConstrain=false, isSoft=true) = ("one" : String)
[error]    |         ==> lub(Nothing, (("two" : String), ("three" : String)), canConstrain=false, isSoft=true)
[error]    |         <== lub(Nothing, (("two" : String), ("three" : String)), canConstrain=false, isSoft=true) = (("two" : String), ("three" : String))
[error]    |         ==> lub(Nothing, ("two" : String), canConstrain=false, isSoft=true)
[error]    |         <== lub(Nothing, ("two" : String), canConstrain=false, isSoft=true) = ("two" : String)
[error]    |         ==> lub(Nothing, ("three" : String) *: EmptyTuple.type, canConstrain=false, isSoft=true)
[error]    |         <== lub(Nothing, ("three" : String) *: EmptyTuple.type, canConstrain=false, isSoft=true) = ("three" : String) *: EmptyTuple.type
[error]    |         ==> lub(Nothing, ("three" : String), canConstrain=false, isSoft=true)
[error]    |         <== lub(Nothing, ("three" : String), canConstrain=false, isSoft=true) = ("three" : String)
[error]    |         ==> lub(Nothing, EmptyTuple.type, canConstrain=false, isSoft=true)
[error]    |         <== lub(Nothing, EmptyTuple.type, canConstrain=false, isSoft=true) = EmptyTuple.type
[error]    |         ==> ("one" : String) | (("two" : String) | (("three" : String) | Nothing))  <:  Nothing
[error]    |           ==> String  <:  Nothing in frozen constraint
[error]    |           <== String  <:  Nothing in frozen constraint = false
[error]    |           ==> ("one" : String)  <:  Nothing
[error]    |             ==> String  <:  Nothing (left is approximated)
[error]    |             <== String  <:  Nothing (left is approximated) = false
[error]    |           <== ("one" : String)  <:  Nothing = false
[error]    |         <== ("one" : String) | (("two" : String) | (("three" : String) | Nothing))  <:  Nothing = false
[error]    |       <== Tuple.Union[(?1 : (("one" : String), ("two" : String), ("three" : String)))]  <:  Nothing = false
[error]    |     <== Tuple.Union[(?1 : (("one" : String), ("two" : String), ("three" : String)))]  <:  ("one" : String) | (("two" : String) | (("three" : String) | Nothing)) = false
[error]    |   <== List[   Tuple.Union[(?1 : (("one" : String), ("two" : String), ("three" : String)))] ]  <:  List[("one" : String) | (("two" : String) | (("three" : String) | Nothing))] = false

Expectation

That it will compile on the latest Scala compiler version.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions