-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
reflection: Symbol.typeMembers has a non-deterministic order on classes with more than 5 type parameters/members #22472
Comments
What's interesting is that it's non-deterministic across Scala versions... scala-cli run . -S 3.6.3
# Compiling project (Scala 3.6.3, JVM (23))
# Compiled project (Scala 3.6.3, JVM (23))
# List(type A, type B, type C, type D)
# List(type A, type E, type D, type B, type C)
scala-cli run . -S 3.3.4
# Compiling project (Scala 3.3.4, JVM (23))
# Compiled project (Scala 3.3.4, JVM (23))
# List(type A, type B, type C, type D)
# List(type A, type D, type C, type E, type B)
scala-cli run . -S 3.3.5
# Compiling project (Scala 3.3.5, JVM (23))
# Compiled project (Scala 3.3.5, JVM (23))
# List(type A, type B, type C, type D)
# List(type A, type C, type E, type D, type B)
scala-cli run . -S 3.nightly
# Compiling project (Scala 3.7.0-RC1-bin-20250129-81e057a-NIGHTLY, JVM (23))
# Compiled project (Scala 3.7.0-RC1-bin-20250129-81e057a-NIGHTLY, JVM (23))
# List(type A, type B, type C, type D)
# List(type B, type D, type A, type C, type E) |
Indeed, trait Foo[+A]
trait Bar[A] extends Foo[A] |
This is misleading and, at the very least, should be documented with a docstring. I think the underlying collection should either be changed to an ordered set or the signature updated. |
@prolativ |
Compiler version
3.3.4
Minimized code
Output
Expectation
The list returned by
.typeMembers
is ordered by declaration order, with type parameters first and type members second. BUT only if the total number of type members + type parameters is less than 5. Otherwise the order is non-deterministic due to underlying usage ofSet
.I think expecting a defined order in
Symbold.typeMembers
method is reasonable, because:.typeMembers.filter(_.isTypeParam)
– indicating that this is the correct usage pattern..typeMembers
is very hard - the only way I found is to match type parameter names with the same from.primaryConstructor
- and that's hardly intuitive and I'm not even sure if all types that can have variance defined on type parameters also have a primaryConstructor, otherwise the order is not restorable.List
, not aSet
, indicating order.A user of
izumi-reflect
uncovered this undefined behavior due to getting incorrect variance in typetags generated by izumi-reflect on classes with many type parameters: zio/izumi-reflect#511I'm not sure there's a bulletproof workaround for this issue downstream – because I'm not sure if every relevant type that may be inspected by izumi-reflect has a .primaryConstructor to match order against.
The text was updated successfully, but these errors were encountered: