Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tuples created through *: do not have a Mirror.Of[T] #14127

Closed
juanjovazquez opened this issue Dec 17, 2021 · 11 comments · Fixed by #15250
Closed

Tuples created through *: do not have a Mirror.Of[T] #14127

juanjovazquez opened this issue Dec 17, 2021 · 11 comments · Fixed by #15250

Comments

@juanjovazquez
Copy link

Compiler version

3.1.1-RC1
3.1.0

Minimized code

summon[Mirror.Of[Int *: String *: Boolean *: EmptyTuple]]

Output

no implicit argument of type deriving.Mirror.Of[Int *: String *: Boolean *: EmptyTuple] was found for parameter x of method summon in object Predef

Expectation

Output should be the same as:

summon[Mirror.Of[(Int, String, Boolean)]]

since

summon[(Int, String, Boolean) =:= (Int *: String *: Boolean *: EmptyTuple)]

The cause seems related to the fact that *: is an abstract class and those are excluded from being generic products. Relevant links:
https://github.com/lampepfl/dotty/blob/7a473349b3fb64e7c6c9dfcfb02758f4a2e3756c/library/src/scala/Tuple.scala#L318

https://github.com/lampepfl/dotty/blob/7a473349b3fb64e7c6c9dfcfb02758f4a2e3756c/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala#L233

https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/SymUtils.scala#L77-L88

@odersky
Copy link
Contributor

odersky commented Dec 19, 2021

Isn't that a duplicate of some other issues? I could swear I have seen that discussed recently.

@bishabosha
Copy link
Member

This seems related to #11008 maybe (not the same underlying issue, just whether we consider generic tuple types a Product)

@joroKr21
Copy link
Member

What should be the element names? _n beyond 22? Just realised we can't call _n on an inductive tuple.

@nicolasstucki
Copy link
Contributor

Beyond 22 we do not use _ names. There we use the apply method to access the elements by index (0 based in that casse).

@joroKr21
Copy link
Member

joroKr21 commented Jan 3, 2022

Right but if we implement Mirror for *: tuples we need to provide something as the field names, otherwise it won't work. And we can't call _n on *: below 22 either.

@nicolasstucki
Copy link
Contributor

Then we probably are missing a generalization/extension for mirrors that can handle generic tuples.

@armanbilge
Copy link
Contributor

Not sure if it deserves its own issue, but seems that EmptyTuple itself doesn't have a Mirror.

@bishabosha
Copy link
Member

bishabosha commented Apr 19, 2022

Not sure if it deserves its own issue, but seems that EmptyTuple itself doesn't have a Mirror.

seems that EmptyTuple was never made a case object, so that's why (@nicolasstucki do you remember why?) - also neither is *: a case class, I would guess that both are not because they are meant to substitute for tuples of some sort.

@nicolasstucki
Copy link
Contributor

There was no real reason why we did not make EmptyTuple a case object. Maybe we followed the design of the *:.

The *: cannot be a case class because it is not a real runtime class. The TupleN classes from Scala 2 are used and a new TupleXXL for larger cases (above 22).

I'm trying to make EmptyTuple a case object in #14972 to see if we can.

@bishabosha
Copy link
Member

bishabosha commented Apr 22, 2022

Right but if we implement Mirror for *: tuples we need to provide something as the field names, otherwise it won't work. And we can't call _n on *: below 22 either.

there is no requirement from the definitions of Mirror.SumOf or Mirror.ProductOf that Mirrors have the MirroredElemLabels type member, so we could avoid adding that refinement for generic tuples?
Edit: sorry it is in the Mirror trait definiton

@bishabosha
Copy link
Member

bishabosha commented May 20, 2022

perhaps for tupleXXL we can use as labels (..., "apply(22)", "apply(23)",...)?
or add a new type member for indicating generic size? IndexedAccess = true (and the usual _n labels)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants