@@ -18,6 +18,8 @@ import config.Printers.patmatch
18
18
object PatMat {
19
19
import ast .tpd ._
20
20
21
+ final val selfCheck = true
22
+
21
23
abstract class Node
22
24
23
25
class Translator (implicit ctx : Context ) {
@@ -142,22 +144,17 @@ object PatMat {
142
144
val tpe = label.info.finalResultType
143
145
}
144
146
145
- def isVarPattern (pat : Tree ): Boolean = pat match {
146
- case x : BackquotedIdent => false
147
- case x : Ident => x.name.isVariableName
148
- case _ => false
149
- }
150
-
151
147
/** A conservative approximation of which patterns do not discern anything.
152
148
* They are discarded during the translation.
153
149
*/
154
150
object WildcardPattern {
155
151
def unapply (pat : Tree ): Boolean = pat match {
156
152
case Typed (_, tpt) if tpt.tpe.isRepeatedParam => true
157
153
case Bind (nme.WILDCARD , WildcardPattern ()) => true // don't skip when binding an interesting symbol!
158
- case t if (isWildcardArg(t)) => true
159
- case x : Ident => isVarPattern(x)
160
- case Alternative (ps) => ps forall unapply
154
+ case t if isWildcardArg(t) => true
155
+ case x : BackquotedIdent => false
156
+ case x : Ident => x.name.isVariableName
157
+ case Alternative (ps) => ps.forall(unapply)
161
158
case EmptyTree => true
162
159
case _ => false
163
160
}
@@ -189,12 +186,12 @@ object PatMat {
189
186
case Nil => onSuccess
190
187
}
191
188
192
- def translateElems (seqSym : Symbol , args : List [Tree ], exact : Boolean , onSuccess : Node ) = {
193
- val selectors = args.indices.toList.map(idx =>
194
- ref(seqSym).select(nme.apply).appliedTo(Literal (Constant (idx))))
195
- new LengthTest (seqSym, args.length, exact,
196
- translateArgs(selectors, args, onSuccess), onFailure)
197
- }
189
+ def translateElems (seqSym : Symbol , args : List [Tree ], exact : Boolean , onSuccess : Node ) = {
190
+ val selectors = args.indices.toList.map(idx =>
191
+ ref(seqSym).select(nme.apply).appliedTo(Literal (Constant (idx))))
192
+ new LengthTest (seqSym, args.length, exact,
193
+ translateArgs(selectors, args, onSuccess), onFailure)
194
+ }
198
195
199
196
def translateUnApplySeq (getResult : Symbol , args : List [Tree ]): Node = args.lastOption match {
200
197
case Some (VarArgPattern (arg)) =>
@@ -215,25 +212,25 @@ object PatMat {
215
212
}
216
213
217
214
def translateUnApply (unapp : Tree , args : List [Tree ]): Node = {
218
- def caseClass = unapp.symbol.owner.linkedClass
219
- lazy val caseAccessors = caseClass.caseAccessors.filter(_.is(Method ))
220
- if (isSyntheticScala2Unapply(unapp.symbol) && caseAccessors.length == args.length)
221
- translateArgs(caseAccessors.map(ref(scrutinee).select(_)), args, onSuccess)
222
- else if (unapp.tpe.isRef(defn.BooleanClass ))
223
- new GuardTest (unapp, onSuccess, onFailure)
224
- else {
225
- letAbstract(unapp) { unappResult =>
226
- val isUnapplySeq = unapp.symbol.name == nme.unapplySeq
227
- if (isProductMatch(unapp.tpe.widen, args.length) && ! isUnapplySeq) {
228
- val selectors = productSelectors(unapp.tpe).take(args.length)
229
- .map(ref(unappResult).select(_))
230
- translateArgs(selectors, args, onSuccess)
231
- }
232
- else {
233
- assert(isGetMatch(unapp.tpe))
234
- val get = ref(unappResult).select(nme.get, _.info.isParameterless)
235
- letAbstract(get) { getResult =>
236
- if (isUnapplySeq)
215
+ def caseClass = unapp.symbol.owner.linkedClass
216
+ lazy val caseAccessors = caseClass.caseAccessors.filter(_.is(Method ))
217
+ if (isSyntheticScala2Unapply(unapp.symbol) && caseAccessors.length == args.length)
218
+ translateArgs(caseAccessors.map(ref(scrutinee).select(_)), args, onSuccess)
219
+ else if (unapp.tpe.isRef(defn.BooleanClass ))
220
+ new GuardTest (unapp, onSuccess, onFailure)
221
+ else {
222
+ letAbstract(unapp) { unappResult =>
223
+ val isUnapplySeq = unapp.symbol.name == nme.unapplySeq
224
+ if (isProductMatch(unapp.tpe.widen, args.length) && ! isUnapplySeq) {
225
+ val selectors = productSelectors(unapp.tpe).take(args.length)
226
+ .map(ref(unappResult).select(_))
227
+ translateArgs(selectors, args, onSuccess)
228
+ }
229
+ else {
230
+ assert(isGetMatch(unapp.tpe))
231
+ val get = ref(unappResult).select(nme.get, _.info.isParameterless)
232
+ letAbstract(get) { getResult =>
233
+ if (isUnapplySeq)
237
234
translateUnApplySeq(getResult, args)
238
235
else {
239
236
val selectors =
@@ -254,7 +251,8 @@ object PatMat {
254
251
translatePattern(casted, pat, onSuccess, onFailure)),
255
252
onFailure)
256
253
case UnApply (extractor, implicits, args) =>
257
- var unapp = extractor.appliedTo(ref(scrutinee))
254
+ val mt @ MethodType (_) = extractor.tpe.widen
255
+ var unapp = extractor.appliedTo(ref(scrutinee).ensureConforms(mt.paramInfos.head))
258
256
if (implicits.nonEmpty) unapp = unapp.appliedToArgs(implicits)
259
257
translateUnApply(unapp, args)
260
258
case Bind (name, body) =>
@@ -376,20 +374,22 @@ object PatMat {
376
374
val seen = mutable.Set [Int ]()
377
375
378
376
def emit (node : Node ): Tree = {
379
- assert(node.isInstanceOf [CallNode ] || ! seen.contains(node.id), node.id)
380
- seen += node.id
377
+ if (selfCheck) {
378
+ assert(node.isInstanceOf [CallNode ] || ! emitted.contains(node.id), node.id)
379
+ emitted += node.id
380
+ }
381
381
node match {
382
- case node : Test =>
383
- If (node.condition, emit(node.onSuccess), emit(node.onFailure)).withPos(node.pos)
384
- case node @ LetNode (sym, body) =>
385
- val symDef =
386
- if (sym.is(Label )) DefDef (sym, emit(labelled(sym)))
387
- else ValDef (sym, rhs(sym).ensureConforms(sym.info))
388
- seq(symDef :: Nil , emit(body))
389
- case BodyNode (tree) =>
390
- tree
391
- case CallNode (label) =>
392
- ref(label).ensureApplied
382
+ case node : Test =>
383
+ If (node.condition, emit(node.onSuccess), emit(node.onFailure)).withPos(node.pos)
384
+ case node @ LetNode (sym, body) =>
385
+ val symDef =
386
+ if (sym.is(Label )) DefDef (sym, emit(labelled(sym)))
387
+ else ValDef (sym, rhs(sym).ensureConforms(sym.info))
388
+ seq(symDef :: Nil , emit(body))
389
+ case BodyNode (tree) =>
390
+ tree
391
+ case CallNode (label) =>
392
+ ref(label).ensureApplied
393
393
}
394
394
}
395
395
@@ -455,7 +455,7 @@ class PatMat extends MiniPhaseTransform {
455
455
// check exhaustivity and unreachability
456
456
val engine = new patmat.SpaceEngine
457
457
458
- if (engine.checkable(tree) && false ) {
458
+ if (engine.checkable(tree)) {
459
459
engine.checkExhaustivity(tree)
460
460
engine.checkRedundancy(tree)
461
461
}
0 commit comments