Skip to content

Commit 675f937

Browse files
committed
docs
1 parent baf568d commit 675f937

File tree

1 file changed

+31
-9
lines changed

1 file changed

+31
-9
lines changed

src/compiler/scala/tools/nsc/transform/Fields.scala

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,41 @@ import symtab.Flags._
1414
*
1515
* For traits:
1616
*
17-
* - Namers translates a definition `val x = rhs` into a getter `def x = rhs`
17+
* - Namers translates a definition `val x = rhs` into a getter `def x = rhs` -- no underlying field is created.
1818
* - This phase moves `rhs` into a block nested under the template's local dummy.
1919
* If the value is memoized (stored), the block's final expression assigns the value to the val,
2020
* and the val itself is left without a rhs.
21-
* (Dotty uses a method `x$compute` instead of a block, which is used in the constructor to initialize the val.
22-
* It also unifies strict and lazy vals, in that the RHS is lifted to a method for both.)
23-
* If the value of the rhs is a literal or unit, it is not stored and the final expression of the block is ().
24-
* The val then retains this statically known value as its rhs, with its side-effects still lifted to the block.
25-
* - This phases also synthesizes accessors and fields for any vals mixed into a non-trait class.
26-
* - Constructors moves the expressions in the template into the constructor,
27-
* which means it will initialize the values defined in this template.
21+
* If the value of the rhs is a literal (ConstantType), it is not stored and the final expression of the block is ().
22+
* The val then retains this statically known value as its rhs.
23+
* (We could extend this to other fields that needn't be stored,
24+
* but would still need to lift their side-effects to the block.
25+
* We're mostly to set up for this, and experimented with doing this for Unit-typed vals.
26+
* No longer storing and writing to fields is too much of a a change in semantics.
27+
* Mainly regarding the memory model -- visibility of writes across threads etc would change.)
28+
* - This phase also synthesizes accessors and fields for any vals mixed into a non-trait class.
29+
* - Constructors moves the statements in the template into the constructor,
30+
* which means it will initialize the fields defined in this template (and execute the corresponding side effects).
2831
*
29-
* Runs before erasure (to get bridges), but before lambdalift/flatten, so nested functions/definitions must be considered.
32+
* Runs before erasure (to get bridges), and thus before lambdalift/flatten, so that nested functions/definitions must be considered.
33+
*
34+
* TODO:
35+
* - remove backwards compatibility hacks to complete migration to Java 8-encoding of traits
36+
* - minimize introduction of new flag bits?
37+
* - ...
38+
*
39+
* In the future, would like to get closer to dotty, which lifts a val's RHS to a method `x$compute` instead of a block,
40+
* which is used in the constructor to initialize the val.
41+
* This makes for a nice unification of strict and lazy vals,in that the RHS is lifted to a method for both,
42+
* with the corresponding compute method called at the appropriate time.)
43+
*
44+
* In the even longer term, I agree with @DarkDimius that it would make sense to
45+
* hide the difference between strict and lazy vals. All vals are lazy,
46+
* but the memoization overhead is removed when we statically know they are forced during initialiation.
47+
* We could still expose the low-level field semantics through `private[this] val`s.
48+
*
49+
* In any case, the current behavior of overriding vals is pretty surprising.
50+
* An overridden val's side-effect is still performed.
51+
* The only change due to overriding is that its value is never written to the field (the overridden val's value is, of course).
3052
*/
3153
abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransformers {
3254

0 commit comments

Comments
 (0)