Skip to content

Commit e325601

Browse files
committed
Fixes to PatMat
1 parent f55959c commit e325601

File tree

2 files changed

+47
-43
lines changed

2 files changed

+47
-43
lines changed

compiler/src/dotty/tools/dotc/config/Printers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ object Printers {
3232
val pickling: Printer = noPrinter
3333
val inlining: Printer = noPrinter
3434
val exhaustivity: Printer = noPrinter
35-
val patmatch: Printer = new Printer
35+
val patmatch: Printer = noPrinter
3636
val simplify: Printer = noPrinter
3737
}

compiler/src/dotty/tools/dotc/transform/PatMat.scala

Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)