1
1
package dotty .tools .dotc
2
2
package typer
3
3
4
+ import scala .language .{unsafeNulls => _ }
5
+
4
6
import java .lang .ArithmeticException
5
7
6
8
import ast ._
@@ -74,7 +76,7 @@ object ConstFold:
74
76
private def withFoldedType (c : Constant | Null ): T =
75
77
if c == null then tree else tree.withType(ConstantType (c)).asInstanceOf [T ]
76
78
77
- private def foldUnop (op : Name , x : Constant ): Constant = (op, x.tag) match {
79
+ private def foldUnop (op : Name , x : Constant ): Constant | Null = (op, x.tag) match {
78
80
case (nme.UNARY_! , BooleanTag ) => Constant (! x.booleanValue)
79
81
80
82
case (nme.UNARY_~ , IntTag ) => Constant (~ x.intValue)
@@ -96,7 +98,7 @@ object ConstFold:
96
98
/** These are local helpers to keep foldBinop from overly taxing the
97
99
* optimizer.
98
100
*/
99
- private def foldBooleanOp (op : Name , x : Constant , y : Constant ): Constant = op match {
101
+ private def foldBooleanOp (op : Name , x : Constant , y : Constant ): Constant | Null = op match {
100
102
case nme.ZOR => Constant (x.booleanValue | y.booleanValue)
101
103
case nme.OR => Constant (x.booleanValue | y.booleanValue)
102
104
case nme.XOR => Constant (x.booleanValue ^ y.booleanValue)
@@ -106,7 +108,7 @@ object ConstFold:
106
108
case nme.NE => Constant (x.booleanValue != y.booleanValue)
107
109
case _ => null
108
110
}
109
- private def foldSubrangeOp (op : Name , x : Constant , y : Constant ): Constant = op match {
111
+ private def foldSubrangeOp (op : Name , x : Constant , y : Constant ): Constant | Null = op match {
110
112
case nme.OR => Constant (x.intValue | y.intValue)
111
113
case nme.XOR => Constant (x.intValue ^ y.intValue)
112
114
case nme.AND => Constant (x.intValue & y.intValue)
@@ -126,7 +128,7 @@ object ConstFold:
126
128
case nme.MOD => Constant (x.intValue % y.intValue)
127
129
case _ => null
128
130
}
129
- private def foldLongOp (op : Name , x : Constant , y : Constant ): Constant = op match {
131
+ private def foldLongOp (op : Name , x : Constant , y : Constant ): Constant | Null = op match {
130
132
case nme.OR => Constant (x.longValue | y.longValue)
131
133
case nme.XOR => Constant (x.longValue ^ y.longValue)
132
134
case nme.AND => Constant (x.longValue & y.longValue)
@@ -146,7 +148,7 @@ object ConstFold:
146
148
case nme.MOD => Constant (x.longValue % y.longValue)
147
149
case _ => null
148
150
}
149
- private def foldFloatOp (op : Name , x : Constant , y : Constant ): Constant = op match {
151
+ private def foldFloatOp (op : Name , x : Constant , y : Constant ): Constant | Null = op match {
150
152
case nme.EQ => Constant (x.floatValue == y.floatValue)
151
153
case nme.NE => Constant (x.floatValue != y.floatValue)
152
154
case nme.LT => Constant (x.floatValue < y.floatValue)
@@ -160,7 +162,7 @@ object ConstFold:
160
162
case nme.MOD => Constant (x.floatValue % y.floatValue)
161
163
case _ => null
162
164
}
163
- private def foldDoubleOp (op : Name , x : Constant , y : Constant ): Constant = op match {
165
+ private def foldDoubleOp (op : Name , x : Constant , y : Constant ): Constant | Null = op match {
164
166
case nme.EQ => Constant (x.doubleValue == y.doubleValue)
165
167
case nme.NE => Constant (x.doubleValue != y.doubleValue)
166
168
case nme.LT => Constant (x.doubleValue < y.doubleValue)
@@ -174,21 +176,21 @@ object ConstFold:
174
176
case nme.MOD => Constant (x.doubleValue % y.doubleValue)
175
177
case _ => null
176
178
}
177
- private def foldStringOp (op : Name , x : Constant , y : Constant ): Constant = op match {
179
+ private def foldStringOp (op : Name , x : Constant , y : Constant ): Constant | Null = op match {
178
180
case nme.ADD => Constant (x.stringValue + y.stringValue)
179
181
case nme.EQ => Constant (x.stringValue == y.stringValue)
180
182
case nme.NE => Constant (x.stringValue != y.stringValue)
181
183
case _ => null
182
184
}
183
185
184
- private def foldNullOp (op : Name , x : Constant , y : Constant ): Constant =
186
+ private def foldNullOp (op : Name , x : Constant , y : Constant ): Constant | Null =
185
187
assert(x.tag == NullTag || y.tag == NullTag )
186
188
op match
187
189
case nme.EQ => Constant (x.tag == y.tag)
188
190
case nme.NE => Constant (x.tag != y.tag)
189
191
case _ => null
190
192
191
- private def foldBinop (op : Name , x : Constant , y : Constant ): Constant =
193
+ private def foldBinop (op : Name , x : Constant , y : Constant ): Constant | Null =
192
194
val optag =
193
195
if (x.tag == y.tag) x.tag
194
196
else if (x.isNumeric && y.isNumeric) math.max(x.tag, y.tag)
0 commit comments