@@ -33,7 +33,7 @@ The checker will report:
33
33
| ^
34
34
| Access non- initialized field value localFile. Calling trace :
35
35
| -> val extension : String = name.substring(4 ) [ AbstractFile .scala: 3 ]
36
- | -> def name : String = localFile [ AbstractFile .scala: 8 ]
36
+ | -> def name : String = localFile [ AbstractFile .scala: 8 ]
37
37
```
38
38
39
39
### Inner-Outer Interaction
@@ -56,9 +56,9 @@ The checker will report:
56
56
5 | private var counter = 0 // error
57
57
| ^
58
58
| Access non- initialized field variable counter. Calling trace :
59
- | -> val theEmptyValDef = new EmptyValDef [ trees.scala: 4 ]
60
- | -> class EmptyValDef extends ValDef [ trees.scala: 3 ]
61
- | -> class ValDef { counter += 1 } [ trees.scala: 2 ]
59
+ | -> val theEmptyValDef = new EmptyValDef [ trees.scala: 4 ]
60
+ | -> class EmptyValDef extends ValDef [ trees.scala: 3 ]
61
+ | -> class ValDef { counter += 1 } [ trees.scala: 2 ]
62
62
```
63
63
64
64
### Functions
@@ -84,9 +84,9 @@ The checker reports:
84
84
7 | val b = " hello" // error
85
85
| ^
86
86
| Access non- initialized field value b. Calling trace :
87
- | -> val a = f() [ features- high- order.scala: 6 ]
87
+ | -> val a = f() [ features- high- order.scala: 6 ]
88
88
| -> val f : () => String = () => this .message [ features- high- order.scala: 2 ]
89
- | -> def message : String = b [ features- high- order.scala: 8 ]
89
+ | -> def message : String = b [ features- high- order.scala: 8 ]
90
90
```
91
91
92
92
## Design Goals
@@ -114,14 +114,34 @@ _stackability_, _monotonicity_ and _scopability_.
114
114
115
115
Stackability means that objects are initialized in stack order: if the
116
116
object ` b ` is created during the initialization of object ` a ` , then
117
- ` b ` should become transitively initialized before or at the same time as ` a ` .
118
- Scala enforces this property in syntax, except for the language
119
- feature below:
117
+ ` b ` should become transitively initialized before or at the same time
118
+ as ` a ` . Scala enforces this property in syntax by demanding that all
119
+ fields are initialized at the end of the primary constructor, except
120
+ for the language feature below:
120
121
121
122
``` scala
122
123
var x : T = _
123
124
```
124
125
126
+ Control effects such as exceptions may break this property, as the
127
+ following example shows:
128
+
129
+ ``` scala
130
+ class MyException (val b : B ) extends Exception (" " )
131
+ class A {
132
+ val b = try { new B } catch { case myEx : MyException => myEx.b }
133
+ println(b.a)
134
+ }
135
+ class B {
136
+ throw new MyException (this )
137
+ val a : Int = 1
138
+ }
139
+ ```
140
+
141
+ In the code above, the control effect teleport the uninitialized value
142
+ wrapped in an exception. In the implementation, we avoid the problem
143
+ by ensuring that the values that are thrown must be transitively initialized.
144
+
125
145
Monotonicity means that the initialization status of an object should
126
146
not go backward: initialized fields continue to be initialized, a
127
147
field points to an initialized object may not later point to an
@@ -146,28 +166,16 @@ typestate_ to ensure soundness in the presence of aliasing
146
166
[ 1] . Otherwise, either soundness will be compromised or we have to
147
167
disallow the usage of already initialized fields.
148
168
149
- Scopability means that given any environment ρ (which are the value
150
- bindings for method parameters) for evaluating an expression ` e ` , the
151
- resulting value is either transitively initialized or it may only
152
- reach uninitialized objects that are reachable from ρ in the heap
153
- before the evaluation. Control effects such as exceptions break this
154
- property, as the following example shows:
155
-
156
- ``` scala
157
- class MyException (val b : B ) extends Exception (" " )
158
- class A {
159
- val b = try { new B } catch { case myEx : MyException => myEx.b }
160
- println(b.a)
161
- }
162
- class B {
163
- throw new MyException (this )
164
- val a : Int = 1
165
- }
166
- ```
167
-
168
- In the code above, the control effect teleport the uninitialized value
169
- wrapped in an exception. In the implementation, we avoid the problem
170
- by ensuring that the values that are thrown must be transitively initialized.
169
+ Scopability means that given any environment ` ρ ` (which are the value
170
+ bindings for method parameters) and heap ` σ ` for evaluating an
171
+ expression ` e ` , if the resulting value reaches an object ` o `
172
+ pre-existent in ` σ ` , then ` o ` is reachable from ` ρ ` in ` σ ` . Control
173
+ effects like coroutines, delimited control, resumable exceptions may
174
+ break the property, as they can transport a value upper in the stack
175
+ (not in scope) to be reachable from the current scope. Static fields
176
+ can also serve as a teleport thus breaks this property. In the
177
+ implementation, we need to enforce that teleported values are
178
+ transitively initialized.
171
179
172
180
With the established principles and design goals, following rules are imposed:
173
181
0 commit comments