Because there is no SLS for Scala 3, to understand the concept of “paths”. I read the Paths definition for Scala 2.13, and confused by the following description:
Blockquote
p.x where p is a path and x is a stable member of p. Stable members are packages or members introduced by object definitions or by value definitions of non-volatile types.
Tried and googled a lot about volatile types, but still cannot know what volatile types should be in Scala 3. Tried some sample codes like Cannot override a type with non-volatile upper bound and cannot override a member with non-volatile type, but they all can be compiled by Scala 3 compiler (that is, the rejected codes in Scala 2 now compiled in Scala 3).
So my questions are:
- what does volatile types mean in Scala 3, any change compared to Scala 2, if Scala 3 still support volatile types? or
- Scala 3 has no volatile types support anymore. and if so, how to understand the case of “p.x”?.
- Maybe the definition is OK, because of the improvement of DOT Calculus, the Scala 3 compiler is more powerful and can deal more cases correctly.
Thanks for your help!
Guofeng
1 Like
Thanks for the linked post. It is helpful.
For that definition about p.x, p.x where p is a path and x is a stable member of p. But how could a package be a stable member (a package is not a value)? could you give a sample about it?
Thanks for your reply.
Why would it need to be a value? Paths are a type level concept, a lot of things there aren’t values. The spec simply defines “stable member” as “packages or members introduced by object definitions or by value definitions”. As the path p
may refer to a package, and packages can contain other packages, x
may also be a package.
An example of where a path referring to a package is used is in import clauses. You can import foo.bar.x
, where x
may be a package, so the path here doesn’t refer to a value or even a type.
1 Like
Thanks for the reply. I have a better understanding now, but one more thing still confuses me: what is the problem with volatile types, for the definition of p.x mentions “non-volatile types”?
The following code pass the type check, but have runtime error. Is it related to volatile type?
scala> class A
| class B extends A
|
| trait C:
| type U >: Null
| trait D:
| type T >: B <: A
|
| val z: D & U = null // volatile types definition: abstract type instance does not have any non-null value
| val y: z.T = new B
|
| class D extends C:
| trait E
| trait F:
| type T = E
| type U = F
|
| def frob(arg: E): E = arg
|
// defined class A
// defined class B
// defined trait C
// defined class D
scala> val d = new D
val d: D = D@1dbeedff
scala> d.frob(d.y)
java.lang.ClassCastException: class rs$line$1$B cannot be cast to class rs$line$1$D$E (rs$line$1$B and rs$line$1$D$E are in unnamed module of loader dotty.tools.repl.AbstractFileClassLoader @7fcff1b9)
... 32 elided
“D & U” should be a volatile type (right?), because U is abstract type and D contributes abstract member T to “D & U”. How about “z.T”? z is the instance of the volatile type. Maybe z is the part in p, so it is type check.
Anyway, understanding volatile type is tough.
Thanks for your help again.
BTW, the above code adapted for Scala 3 based on Cannot override a type with non-volatile upper bound