@@ -87,6 +87,17 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
87
87
case None => true
88
88
}
89
89
case t : This => true
90
+ // null => false, or the following fails devalify:
91
+ // trait I {
92
+ // def foo: Any = null
93
+ // }
94
+ // object Main {
95
+ // def main = {
96
+ // val s: I = null
97
+ // s.foo
98
+ // }
99
+ // }
100
+ case Literal (Constant (null )) => false
90
101
case t : Literal => true
91
102
case _ => false
92
103
}
@@ -114,21 +125,21 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
114
125
*/
115
126
type Optimization = (Context ) => (String , ErasureCompatibility , Visitor , Transformer )
116
127
117
- private lazy val _optimizations : Seq [Optimization ] = Seq (
118
- inlineCaseIntrinsics
119
- , removeUnnecessaryNullChecks
120
- , inlineOptions
121
- , inlineLabelsCalledOnce
122
- , valify
123
- , devalify
124
- , jumpjump
125
- , dropGoodCasts
126
- , dropNoEffects
127
- , inlineLocalObjects // followCases needs to be fixed, see ./tests/pos/rbtree.scala
128
- /* , varify*/ // varify could stop other transformations from being applied. postponed.
129
- // , bubbleUpNothing
130
- , constantFold
131
- )
128
+ private lazy val _optimizations : Seq [Optimization ] =
129
+ inlineCaseIntrinsics ::
130
+ removeUnnecessaryNullChecks ::
131
+ inlineOptions ::
132
+ inlineLabelsCalledOnce ::
133
+ valify ::
134
+ devalify ::
135
+ jumpjump ::
136
+ dropGoodCasts ::
137
+ dropNoEffects ::
138
+ // inlineLocalObjects :: // followCases needs to be fixed, see ./tests/pos/rbtree.scala
139
+ // varify :: // varify could stop other transformations from being applied. postponed.
140
+ // bubbleUpNothing ::
141
+ constantFold ::
142
+ Nil
132
143
133
144
override def transformDefDef (tree : DefDef )(implicit ctx : Context , info : TransformerInfo ): Tree = {
134
145
val ctx0 = ctx
@@ -184,8 +195,13 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
184
195
*/
185
196
val inlineCaseIntrinsics : Optimization = { implicit ctx : Context =>
186
197
val transformer : Transformer = () => localCtx => {
187
- case a : Apply if ! a.tpe.isInstanceOf [MethodicType ] && a.symbol.is(Flags .Synthetic ) && a.symbol.owner.is(Flags .Module ) &&
188
- (a.symbol.name == nme.apply) && a.symbol.owner.companionClass.is(Flags .CaseClass ) =>
198
+ case a : Apply if ! a.tpe.isInstanceOf [MethodicType ] &&
199
+ a.symbol.is(Flags .Synthetic ) &&
200
+ a.symbol.owner.is(Flags .Module ) &&
201
+ (a.symbol.name == nme.apply) &&
202
+ a.symbol.owner.companionClass.is(Flags .CaseClass ) &&
203
+ ! a.tpe.derivesFrom(defn.EnumClass ) &&
204
+ isPureExpr(a.tree) =>
189
205
def unrollArgs (t : Tree , l : List [List [Tree ]]): List [List [Tree ]] = t match {
190
206
case Apply (t, args) => unrollArgs(t, args :: l)
191
207
case _ => l
@@ -195,9 +211,15 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
195
211
case head :: tail => rollInArgs(tail, fun.appliedToArgs(head))
196
212
case _ => fun
197
213
}
198
- rollInArgs(argss.tail, tpd.New (a.tpe.dealias, argss.head))
199
- case a : Apply if a.symbol.is(Flags .Synthetic ) && a.symbol.owner.is(Flags .Module ) &&
200
- (a.symbol.name == nme.unapply) && a.symbol.owner.companionClass.is(Flags .CaseClass ) =>
214
+ val constructor = a.symbol.owner.companionClass.primaryConstructor.asTerm
215
+ rollInArgs(argss.tail, New (a.tpe.widenDealias, constructor, argss.head))
216
+
217
+ case a : Apply if a.symbol.is(Flags .Synthetic ) &&
218
+ a.symbol.owner.is(Flags .Module ) &&
219
+ (a.symbol.name == nme.unapply) &&
220
+ a.symbol.owner.companionClass.is(Flags .CaseClass ) &&
221
+ ! a.tpe.derivesFrom(defn.EnumClass ) &&
222
+ isPureExpr(a.tree) =>
201
223
if (! a.symbol.owner.is(Flags .Scala2x )) {
202
224
if (a.tpe.derivesFrom(defn.BooleanClass )) Literal (Constant (true ))
203
225
else a.args.head
@@ -210,14 +232,17 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
210
232
val tplType = a.tpe.baseArgTypes(defn.OptionClass ).head
211
233
212
234
if (fields.tail.nonEmpty) {
213
- val tplAlloc = tpd. New (tplType, fields)
214
- tpd. New (a.tpe.dealias .translateParameterized(defn.OptionClass , defn.SomeClass ), tplAlloc :: Nil )
215
- } else { // scalac does not have tupple1
216
- tpd. New (a.tpe.dealias .translateParameterized(defn.OptionClass , defn.SomeClass ), fields.head :: Nil )
235
+ val tplAlloc = New (tplType, fields)
236
+ New (a.tpe.translateParameterized(defn.OptionClass , defn.SomeClass ), tplAlloc :: Nil )
237
+ } else { // scalac does not have Tuple1
238
+ New (a.tpe.translateParameterized(defn.OptionClass , defn.SomeClass ), fields.head :: Nil )
217
239
}
218
240
}
219
241
else a
220
- case a : Apply if (a.symbol.name == nme.unapplySeq) && a.symbol.owner.derivesFrom(SeqFactoryClass ) && a.symbol.extendedOverriddenSymbols.isEmpty =>
242
+ case a : Apply if (a.symbol.name == nme.unapplySeq) &&
243
+ a.symbol.owner.derivesFrom(SeqFactoryClass ) &&
244
+ a.symbol.extendedOverriddenSymbols.isEmpty &&
245
+ isPureExpr(a.tree) =>
221
246
def reciever (t : Tree ): Type = t match {
222
247
case t : Apply => reciever(t.fun)
223
248
case t : TypeApply => reciever(t.fun)
@@ -231,7 +256,7 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
231
256
232
257
val recv = reciever(a)
233
258
if (recv.typeSymbol.is(Flags .Module ))
234
- tpd. New (a.tpe.dealias .translateParameterized(defn.OptionClass , defn.SomeClass ), a.args.head :: Nil )
259
+ New (a.tpe.translateParameterized(defn.OptionClass , defn.SomeClass ), a.args.head :: Nil )
235
260
else a
236
261
case t => t
237
262
}
@@ -682,7 +707,7 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
682
707
case t : Tree =>
683
708
}
684
709
685
- @ inline def isNullLiteral (tree : Tree ) = tree match {
710
+ def isNullLiteral (tree : Tree ) = tree match {
686
711
case literal : Literal =>
687
712
literal.const.tag == Constants .NullTag
688
713
case _ => false
@@ -982,7 +1007,7 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
982
1007
case t : ValDef if t.symbol.is(Flags .Mutable , Flags .Lazy ) && ! t.symbol.is(Flags .Method ) && ! t.symbol.owner.isClass =>
983
1008
if (isPureExpr(t.rhs))
984
1009
defined(t.symbol) = t
985
- case t : RefTree if ! t.symbol.is(Flags .Method ) && ! t.symbol.owner.isClass =>
1010
+ case t : RefTree if t.symbol.exists && ! t.symbol.is(Flags .Method ) && ! t.symbol.owner.isClass =>
986
1011
if (! firstWrite.contains(t.symbol)) firstRead(t.symbol) = t
987
1012
case t @ Assign (l, expr) if ! l.symbol.is(Flags .Method ) && ! l.symbol.owner.isClass =>
988
1013
if (! firstRead.contains(l.symbol)) {
0 commit comments