@@ -30,15 +30,19 @@ object PatMat {
3030
3131 val sanitize = new TypeMap {
3232 def apply (t : Type ): Type = t.widenExpr match {
33- case t : TermRef
34- if patmatGenerated(t.symbol) || t.info.isInstanceOf [ExprType ] => apply(t.info)
33+ case t : TermRef if patmatGenerated(t.symbol) =>
34+ t.info.widenExpr match {
35+ case t1 : TermRef => apply(t1)
36+ case _ => t
37+ }
3538 case t => mapOver(t)
3639 }
3740 }
3841
3942 case class BinderInfo (rhs : Tree )
4043
4144 val binding = mutable.Map [Symbol , AnyRef /* Tree | Node*/ ]()
45+ val nonNull = mutable.Set [Symbol ]()
4246
4347 def rhs (sym : Symbol ) = {
4448 assert(! sym.is(Label ))
@@ -64,15 +68,14 @@ object PatMat {
6468 }
6569
6670 def newLabel (body : Node ) = {
67- val label = freshLabel(MethodType (Nil , sanitize(body.tpe) ))
71+ val label = freshLabel(MethodType (Nil , resultType ))
6872 binding(label) = body
6973 label
7074 }
7175
7276 private var nxId = 0
7377
7478 sealed abstract class Node {
75- def tpe : Type
7679 val id = nxId
7780 nxId += 1
7881 }
@@ -81,21 +84,14 @@ object PatMat {
8184 def this (scrut : Symbol , ons : Node , onf : Node ) = this (ref(scrut), ons, onf)
8285 def condition : Tree
8386 def pos : Position
84- val tpe =
85- try sanitize(onSuccess.tpe | onFailure.tpe)
86- catch {
87- case ex : AssertionError =>
88- println(i " cannot | $onSuccess: ${onSuccess.tpe} with $onFailure ${onFailure.tpe}" )
89- throw ex
90- }
9187 }
9288
93- class UnApplyTest (scrut : Symbol , ons : Node , onf : Node ) extends Test (scrut, ons, onf) {
89+ class NonEmptyTest (scrut : Symbol , ons : Node , onf : Node ) extends Test (scrut, ons, onf) {
9490 def pos = scrut.pos
9591 def condition = scrutinee
9692 .select(nme.isEmpty, _.info.isParameterless)
9793 .select(nme.UNARY_! , _.info.isParameterless)
98- override def toString = i " UnApplyTest ( $scrutinee) "
94+ override def toString = i " NonEmptyTest ( $scrutinee) "
9995 }
10096
10197 class TypeTest (scrut : Symbol , tpt : Tree , ons : Node , onf : Node ) extends Test (scrut, ons, onf) {
@@ -145,18 +141,22 @@ object PatMat {
145141 override def toString = i " EqualTest( $tree == $scrutinee) "
146142 }
147143
144+ class NonNullTest (scrut : Symbol , ons : Node , onf : Node ) extends Test (scrut, ons, onf) {
145+ def pos = scrut.pos
146+ def condition = scrutinee.testNotNull
147+ }
148+
148149 class LengthTest (scrut : Symbol , len : Int , exact : Boolean , ons : Node , onf : Node ) extends Test (scrut, ons, onf) {
149150 def pos = scrut.pos
150- def condition = scrutinee
151- .select(defn.Any_!= )
152- .appliedTo(Literal (Constant (null )))
153- .select(defn.Boolean_&& )
154- .appliedTo(
151+ def condition = // scrutinee
152+ // .select(defn.Any_!=)
153+ // .appliedTo(Literal(Constant(null)))
154+ // .and(
155155 scrutinee
156156 .select(defn.Seq_lengthCompare .matchingMember(scrutinee.tpe))
157157 .appliedTo(Literal (Constant (len)))
158158 .select(if (exact) defn.Int_== else defn.Int_>= )
159- .appliedTo(Literal (Constant (0 ))))
159+ .appliedTo(Literal (Constant (0 )))// )
160160 override def toString =
161161 i " Lengthtest( $scrutinee.length ${if (exact) " ==" else " >=" } $len) "
162162 }
@@ -167,17 +167,11 @@ object PatMat {
167167 override def toString = i " GuardTest( $scrutinee) "
168168 }
169169
170- case class LetNode (sym : TermSymbol , var body : Node ) extends Node {
171- val tpe = sanitize(body.tpe)
172- }
170+ case class LetNode (sym : TermSymbol , var body : Node ) extends Node
173171
174- case class BodyNode (var tree : Tree ) extends Node {
175- val tpe = tree.tpe
176- }
172+ case class BodyNode (var tree : Tree ) extends Node
177173
178- case class CallNode (label : TermSymbol ) extends Node {
179- val tpe = label.info.finalResultType
180- }
174+ case class CallNode (label : TermSymbol ) extends Node
181175
182176 /** A conservative approximation of which patterns do not discern anything.
183177 * They are discarded during the translation.
@@ -205,8 +199,12 @@ object PatMat {
205199 def isSyntheticScala2Unapply (sym : Symbol ) =
206200 sym.is(SyntheticCase ) && sym.owner.is(Scala2x )
207201
208- def swapBind (tree : Tree ) = tree match {
209- case Bind (name, Typed (pat, tpt)) => Typed (cpy.Bind (tree)(name, pat), tpt)
202+ def swapBind (tree : Tree ): Tree = tree match {
203+ case Bind (name, pat0) =>
204+ swapBind(pat0) match {
205+ case Typed (pat, tpt) => Typed (cpy.Bind (tree)(name, pat), tpt)
206+ case _ => tree
207+ }
210208 case _ => tree
211209 }
212210
@@ -263,17 +261,19 @@ object PatMat {
263261 }
264262 else {
265263 assert(isGetMatch(unapp.tpe))
266- val get = ref(unappResult).select(nme.get, _.info.isParameterless)
267- letAbstract(get) { getResult =>
264+ val argsPlan = {
265+ val get = ref(unappResult).select(nme.get, _.info.isParameterless)
268266 if (isUnapplySeq)
269- translateUnApplySeq(getResult, args)
270- else {
271- val selectors =
272- if (args.tail.isEmpty) ref(getResult) :: Nil
273- else productSelectors(get.tpe).map(ref(getResult).select(_))
274- new UnApplyTest (unappResult, translateArgs(selectors, args, onSuccess), onFailure)
275- }
267+ letAbstract(get)(translateUnApplySeq(_, args))
268+ else
269+ letAbstract(get) { getResult =>
270+ val selectors =
271+ if (args.tail.isEmpty) ref(getResult) :: Nil
272+ else productSelectors(get.tpe).map(ref(getResult).select(_))
273+ translateArgs(selectors, args, onSuccess)
274+ }
276275 }
276+ new NonEmptyTest (unappResult, argsPlan, onFailure)
277277 }
278278 }
279279 }
@@ -282,14 +282,18 @@ object PatMat {
282282 swapBind(tree) match {
283283 case Typed (pat, tpt) =>
284284 new TypeTest (scrutinee, tpt,
285- letAbstract(ref(scrutinee).asInstance(tpt.tpe))(casted =>
286- translatePattern(casted, pat, onSuccess, onFailure)),
285+ letAbstract(ref(scrutinee).asInstance(tpt.tpe)) { casted =>
286+ nonNull += casted
287+ translatePattern(casted, pat, onSuccess, onFailure)
288+ },
287289 onFailure)
288290 case UnApply (extractor, implicits, args) =>
289291 val mt @ MethodType (_) = extractor.tpe.widen
290292 var unapp = extractor.appliedTo(ref(scrutinee).ensureConforms(mt.paramInfos.head))
291293 if (implicits.nonEmpty) unapp = unapp.appliedToArgs(implicits)
292- translateUnApply(unapp, args)
294+ val unapplyPlan = translateUnApply(unapp, args)
295+ if (scrutinee.info.isNotNull || nonNull(scrutinee)) unapplyPlan
296+ else new NonNullTest (scrutinee, unapplyPlan, onFailure)
293297 case Bind (name, body) =>
294298 val body1 = translatePattern(scrutinee, body, onSuccess, onFailure)
295299 if (name == nme.WILDCARD ) body1
0 commit comments