-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generate mirrors for named tuples (#22469)
For `summon[Mirror.Of[(foo: Int, bla: String)]]` we generate: ```scala new scala.runtime.TupleMirror(2).$asInstanceOf[ scala.deriving.Mirror.Product{ type MirroredMonoType = (foo : Int, bla : String); type MirroredType = (foo : Int, bla : String); type MirroredLabel = ("NamedTuple" : String); type MirroredElemTypes = (Int, String); type MirroredElemLabels = (("foo" : String), ("bla" : String)) } ] ``` We reuse scala.runtime.TupleMirror, because it pretty much does everything we want it to, and fromProduct (with supplied Product types) call on that mirror still works there. Since NamedTuple is not technically a `Product` type, I imagine users might be a little confused why they can't put a named tuple into a `fromProduct` argument, but this is easily worked around with `.toTuple`
- Loading branch information
Showing
5 changed files
with
83 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
-- [E172] Type Error: tests/neg/named-tuples-mirror.scala:6:47 --------------------------------------------------------- | ||
6 | summon[Mirror.SumOf[(foo: Int, bla: String)]] // error | ||
| ^ | ||
|No given instance of type scala.deriving.Mirror.SumOf[(foo : Int, bla : String)] was found for parameter x of method summon in object Predef. Failed to synthesize an instance of type scala.deriving.Mirror.SumOf[(foo : Int, bla : String)]: type `(foo : Int, bla : String)` is not a generic sum because named tuples are not sealed classes | ||
-- Error: tests/neg/named-tuples-mirror.scala:9:4 ---------------------------------------------------------------------- | ||
9 | }]// error | ||
| ^ | ||
|MirroredElemLabels mismatch, expected: (("foo" : String), ("bla" : String)), found: (("foo" : String), ("ba" : String)). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import scala.language.experimental.namedTuples | ||
import scala.deriving.* | ||
import scala.compiletime.* | ||
|
||
@main def Test = | ||
summon[Mirror.SumOf[(foo: Int, bla: String)]] // error | ||
val namedTuple = summon[Mirror.Of[(foo: Int, bla: String)]{ | ||
type MirroredElemLabels = ("foo", "ba") | ||
}]// error | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
NamedTuple | ||
List(foo: Int, bla: String) | ||
15 | ||
test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import scala.language.experimental.namedTuples | ||
import scala.deriving.* | ||
import scala.compiletime.* | ||
|
||
type ToString[T] = T match | ||
case Int => "Int" | ||
case String => "String" | ||
|
||
inline def showLabelsAndTypes[Types <: Tuple, Labels <: Tuple]: List[String] = | ||
inline erasedValue[Types] match { | ||
case _: (tpe *: types) => | ||
inline erasedValue[Labels] match { | ||
case _: (label *: labels) => | ||
val labelStr = constValue[label] | ||
val tpeStr = constValue[ToString[tpe]] | ||
s"$labelStr: $tpeStr" :: showLabelsAndTypes[types, labels] | ||
} | ||
case _: EmptyTuple => | ||
Nil | ||
} | ||
|
||
@main def Test = | ||
val mirror = summon[Mirror.Of[(foo: Int, bla: String)]] | ||
println(constValue[mirror.MirroredLabel]) | ||
println(showLabelsAndTypes[mirror.MirroredElemTypes, mirror.MirroredElemLabels]) | ||
|
||
val namedTuple = summon[Mirror.Of[(foo: Int, bla: String)]].fromProduct((15, "test")) | ||
println(namedTuple.foo) | ||
println(namedTuple.bla) |