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

variances are not preserved for 5+ type parameters #511

Closed
memo33 opened this issue Jan 24, 2025 · 6 comments
Closed

variances are not preserved for 5+ type parameters #511

memo33 opened this issue Jan 24, 2025 · 6 comments

Comments

@memo33
Copy link

memo33 commented Jan 24, 2025

From zio/zio-http#3264:

For classes with 5 or more type parameters, the variances seem to be randomly shuffled among the type parameters.

class Foo[-A,B,-C,+D,+E]

izumi.reflect.Tag[Foo[Int, String, Double, Float, Long]].tag

Output is random:

val res0: izumi.reflect.macrortti.LightTypeTag = ::Foo[-Int,+String,=Double,+Float,-Long]
val res0: izumi.reflect.macrortti.LightTypeTag = ::Foo[-Int,+String,-Double,=Float,+Long]
val res0: izumi.reflect.macrortti.LightTypeTag = ::Foo[+Int,-String,=Double,+Float,-Long]

(Tested with izumi-reflect 2.3.10, Scala 3.6.3.)

@pshirshov
Copy link
Member

If it's really random, it makes me think that there is a compiler bug. We've seen similar things before. Probably you should open an upstream issue.

@pshirshov pshirshov unpinned this issue Jan 24, 2025
@pshirshov
Copy link
Member

Another possibility is some subtle bug in our binary tag encoding, but I very much doubt it because there is no concurrent access involved and the code is more or less straightforward. I would try to add some debug logging and see what happens.

@neko-kai
Copy link
Member

neko-kai commented Jan 25, 2025

@memo33 What about Scala 2? Does this reproduce on Scala 2?

EDIT: It does NOT reproduce on Scala 2

@neko-kai
Copy link
Member

neko-kai commented Jan 25, 2025

This IS a bug in Scala 3 Reflection API - specifically Symbol.typeMembers uses a Set underneath and the ordering is non-deterministic for large sets. This is not an API misuse issue, because there's no other way, that I found, using public API to get at type params of an applied concrete type. I'll check tomorrow if maybe I can retrieve a type lambda of a type constructor through its ParamRef retrieved through a .typeMembers call - no other ideas how to restore ordering using public API yet.

EDIT: No, .typeMembers returns TypeRefs, not ParamRefs.

Opened upstream issue: scala/scala3#22472

/cc @nicolasstucki @smarter

@pshirshov
Copy link
Member

pshirshov commented Jan 25, 2025

Ouch. So, I was kinda right. I think it's an API design issue, it returns an ordered collection interface which is backed by an unordered collection.

@memo33
Copy link
Author

memo33 commented Jan 30, 2025

Awesome. Thanks a lot for the quick fix. It works for me.

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

No branches or pull requests

3 participants