@@ -235,18 +235,21 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
235235 else a.args.head
236236 }
237237 else if (a.tpe.derivesFrom(defn.OptionClass ) && a.args.head.tpe.derivesFrom(a.symbol.owner.companionClass)) {
238- // TODO: if args is an expression, this will evaluate it multiple times
239- // TODO: if the static type is right, it does not mean it's not null
240- val accessors = a.args.head.tpe.widenDealias.classSymbol.caseAccessors.filter(_.is(Flags .Method ))
241- val fields = accessors.map(x => a.args.head.select(x).ensureApplied)
242- val tplType = a.tpe.baseArgTypes(defn.OptionClass ).head
243-
244- if (fields.tail.nonEmpty) {
245- val tplAlloc = New (tplType, fields)
246- New (a.tpe.translateParameterized(defn.OptionClass , defn.SomeClass ), tplAlloc :: Nil )
247- } else { // scalac does not have Tuple1
248- New (a.tpe.translateParameterized(defn.OptionClass , defn.SomeClass ), fields.head :: Nil )
238+ def some (e : Tree ) = {
239+ val accessors = e.tpe.widenDealias.classSymbol.caseAccessors.filter(_.is(Method ))
240+ val fields = accessors.map(x => e.select(x).ensureApplied)
241+ val tplType = a.tpe.baseArgTypes(defn.OptionClass ).head
242+ if (fields.tail.nonEmpty) {
243+ val tplAlloc = New (tplType, fields)
244+ New (a.tpe.translateParameterized(defn.OptionClass , defn.SomeClass ), tplAlloc :: Nil )
245+ } else { // scalac does not have Tuple1
246+ New (a.tpe.translateParameterized(defn.OptionClass , defn.SomeClass ), fields.head :: Nil )
247+ }
249248 }
249+ val none = ref(defn.NoneModuleRef )
250+ def isNull (e : Tree ) = e.select(defn.Object_eq ).appliedTo(Literal (Constant (null )))
251+ def fi (e : Tree ) = If (isNull(e), none, some(e))
252+ evalOnce(a.args.head)(fi)
250253 }
251254 else a
252255 case a : Apply if (a.symbol.name == nme.unapplySeq) &&
0 commit comments