Skip to content

Commit 5107c89

Browse files
Squash ExtractorCall and ExtractorCallRegular together
1 parent fe4974c commit 5107c89

File tree

1 file changed

+20
-79
lines changed

1 file changed

+20
-79
lines changed

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

Lines changed: 20 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -563,10 +563,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
563563
// sub patterns bound to wildcard (_) are never stored as they can't be referenced
564564
// dirty debuggers will have to get dirty to see the wildcards
565565
lazy val storedBinders: Set[Symbol] =
566-
(if (debugInfoEmitVars) subPatBinders.toSet else Set.empty) ++ extraStoredBinders -- ignoredSubPatBinders
567-
568-
// e.g., mutable fields of a case class in ProductExtractorTreeMaker
569-
def extraStoredBinders: Set[Symbol]
566+
(if (debugInfoEmitVars) subPatBinders.toSet else Set.empty[Symbol]) -- ignoredSubPatBinders
570567

571568
def emitVars = storedBinders.nonEmpty
572569

@@ -643,8 +640,6 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
643640
val ignoredSubPatBinders: Set[Symbol]
644641
) extends FunTreeMaker with PreserveSubPatBinders {
645642

646-
def extraStoredBinders: Set[Symbol] = Set()
647-
648643
ctx.debuglog(s"""
649644
|ExtractorTreeMaker($extractor, $extraCond, $nextBinder) {
650645
| $subPatBinders
@@ -1348,70 +1343,46 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
13481343
case UnApply(unfun, implicits, args) =>
13491344
val castedBinder = ref(binder).ensureConforms(tree.tpe)
13501345
val synth = if (implicits.isEmpty) unfun.appliedTo(castedBinder) else unfun.appliedTo(castedBinder).appliedToArgs(implicits)
1351-
new ExtractorCallRegular(alignPatterns(tree, synth.tpe), synth, args, synth.tpe)
1346+
new ExtractorCall(alignPatterns(tree, synth.tpe), synth, args, synth.tpe)
13521347
}
13531348
}
13541349
}
13551350

1356-
abstract class ExtractorCall(val aligner: PatternAligned) {
1357-
1351+
class ExtractorCall(val aligner: PatternAligned, extractorCallIncludingDummy: Tree, val args: List[Tree], val resultType: Type) {
13581352
import aligner._
13591353

1360-
def args: List[Tree]
1361-
1362-
// don't go looking for selectors if we only expect one pattern
1363-
def rawSubPatTypes = aligner.extractedTypes
1364-
1365-
def typeArgOfBaseTypeOr(tp: Type, baseClass: Symbol)(or: => Type): Type = (tp.baseTypeWithArgs(baseClass)).argInfos match {
1366-
case x :: Nil => x
1367-
case _ => or
1368-
}
1369-
13701354
def resultInMonad =
13711355
if (aligner.isBool) defn.UnitType
13721356
else if (isProductMatch(resultType, aligner.prodArity)) resultType
13731357
else if (isGetMatch(resultType)) extractorMemberType(resultType, nme.get)
13741358
else resultType
13751359

1376-
def resultType: Type
1377-
1378-
/** Create the TreeMaker that embodies this extractor call
1379-
*
1380-
* `binder` has been casted to `paramType` if necessary
1381-
* `binderKnownNonNull` indicates whether the cast implies `binder` cannot be null
1382-
* when `binderKnownNonNull` is `true`, `ProductExtractorTreeMaker` does not do a (redundant) null check on binder
1383-
*/
1384-
def treeMaker(binder: Symbol, binderKnownNonNull: Boolean, pos: Position, binderTypeTested: Type): TreeMaker
1385-
13861360
// `subPatBinders` are the variables bound by this pattern in the following patterns
13871361
// subPatBinders are replaced by references to the relevant part of the extractor's result (tuple component, seq element, the result as-is)
13881362
// must set infos to `subPatTypes`, which are provided by extractor's result,
13891363
// as b.info may be based on a Typed type ascription, which has not been taken into account yet by the translation
13901364
// (it will later result in a type test when `tp` is not a subtype of `b.info`)
13911365
// TODO: can we simplify this, together with the Bound case?
13921366
def subPatBinders = subBoundTrees map (_.binder)
1393-
lazy val subBoundTrees = (args, subPatTypes).zipped map newBoundTree
1367+
lazy val subBoundTrees = (args, typedPatterns.map(_.tpe)).zipped map newBoundTree
13941368

13951369
// never store these in local variables (for PreserveSubPatBinders)
13961370
lazy val ignoredSubPatBinders: Set[Symbol] = subPatBinders zip args collect { case (b, PatternBoundToUnderscore()) => b } toSet
13971371

1398-
// do repeated-parameter expansion to match up with the expected number of arguments (in casu, subpatterns)
1399-
private def nonStarSubPatTypes = aligner.typedNonStarPatterns map (_.tpe)
1400-
1401-
def subPatTypes: List[Type] = typedPatterns map (_.tpe)
1402-
14031372
// there are `prodArity` non-seq elements in the tuple.
1404-
protected def firstIndexingBinder = prodArity
1405-
protected def expectedLength = elementArity
1406-
protected def lastIndexingBinder = totalArity - starArity - 1
1373+
private def firstIndexingBinder = prodArity
1374+
private def expectedLength = elementArity
1375+
private def lastIndexingBinder = totalArity - starArity - 1
14071376

14081377
private def productElemsToN(binder: Symbol, n: Int): List[Tree] = 1 to n map tupleSel(binder) toList
14091378
private def genTake(binder: Symbol, n: Int): List[Tree] = (0 until n).toList map (codegen index seqTree(binder))
14101379
private def genDrop(binder: Symbol, n: Int): List[Tree] = codegen.drop(seqTree(binder))(expectedLength) :: Nil
14111380

1412-
// codegen.drop(seqTree(binder))(nbIndexingIndices)))).toList
1413-
protected def seqTree(binder: Symbol) = tupleSel(binder)(firstIndexingBinder + 1)
1414-
protected def tupleSel(binder: Symbol)(i: Int): Tree = {
1381+
private def seqTree(binder: Symbol): Tree =
1382+
if (firstIndexingBinder == 0) ref(binder)
1383+
else tupleSel(binder)(firstIndexingBinder + 1)
1384+
1385+
private def tupleSel(binder: Symbol)(i: Int): Tree = {
14151386
val accessors =
14161387
if (defn.isProductSubType(binder.info))
14171388
productSelectors(binder.info)
@@ -1425,7 +1396,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
14251396

14261397
// the trees that select the subpatterns on the extractor's result,
14271398
// referenced by `binder`
1428-
protected def subPatRefsSeq(binder: Symbol): List[Tree] = {
1399+
private def subPatRefsSeq(binder: Symbol): List[Tree] = {
14291400
def lastTrees: List[Tree] = (
14301401
if (!aligner.isStar) Nil
14311402
else if (expectedLength == 0) seqTree(binder) :: Nil
@@ -1446,7 +1417,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
14461417

14471418
// the trees that select the subpatterns on the extractor's result, referenced by `binder`
14481419
// require (nbSubPats > 0 && (!lastIsStar || isSeq))
1449-
protected def subPatRefs(binder: Symbol): List[Tree] = {
1420+
private def subPatRefs(binder: Symbol): List[Tree] = {
14501421
val refs = if (totalArity > 0 && isSeq) subPatRefsSeq(binder)
14511422
else if (binder.info.member(nme._1).exists && !isSeq) productElemsToN(binder, totalArity)
14521423
else ref(binder) :: Nil
@@ -1459,17 +1430,16 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
14591430

14601431
private def compareInts(t1: Tree, t2: Tree) =
14611432
mathSignum.appliedTo(t1.select(defn.Int_-).appliedTo(t2))
1462-
//gen.mkMethodCall(termMember(ScalaPackage, "math"), TermName("signum"), Nil, (t1 INT_- t2) :: Nil)
14631433

1464-
protected def lengthGuard(binder: Symbol): Option[Tree] =
1465-
// no need to check unless it's an unapplySeq and the minimal length is non-trivially satisfied
1434+
private def lengthGuard(binder: Symbol): Option[Tree] =
1435+
// no need to check unless it's an unapplySeq and the minimal length is non-trivially satisfied
14661436
checkedLength map { expectedLength =>
14671437
// `binder.lengthCompare(expectedLength)`
14681438
// ...if binder has a lengthCompare method, otherwise
14691439
// `scala.math.signum(binder.length - expectedLength)`
14701440
def checkExpectedLength: Tree = sequenceType.member(nme.lengthCompare) match {
1471-
case NoDenotation => compareInts(Select(seqTree(binder), nme.length), Literal(Constant(expectedLength)))
1472-
case x:SingleDenotation => (seqTree(binder).select(x.symbol)).appliedTo(Literal(Constant(expectedLength)))
1441+
case NoDenotation => compareInts(Select(seqTree(binder), nme.length), Literal(Constant(expectedLength)))
1442+
case x: SingleDenotation => (seqTree(binder).select(x.symbol)).appliedTo(Literal(Constant(expectedLength)))
14731443
case _ =>
14741444
ctx.error("TODO: multiple lengthCompare")
14751445
EmptyTree
@@ -1487,12 +1457,9 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
14871457
}
14881458

14891459
def checkedLength: Option[Int] =
1490-
// no need to check unless it's an unapplySeq and the minimal length is non-trivially satisfied
1460+
// no need to check unless it's an unapplySeq and the minimal length is non-trivially satisfied
14911461
if (!isSeq || expectedLength < starArity) None
14921462
else Some(expectedLength)
1493-
}
1494-
1495-
class ExtractorCallRegular(aligner: PatternAligned, extractorCallIncludingDummy: Tree, val args: List[Tree], val resultType: Type) extends ExtractorCall(aligner) {
14961463

14971464
/** Create the TreeMaker that embodies this extractor call
14981465
*
@@ -1523,21 +1490,16 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
15231490
)
15241491
}
15251492

1526-
override protected def seqTree(binder: Symbol): Tree =
1527-
if (firstIndexingBinder == 0) ref(binder)
1528-
else super.seqTree(binder)
1529-
15301493
// the trees that select the subpatterns on the extractor's result, referenced by `binder`
15311494
// require (totalArity > 0 && (!lastIsStar || isSeq))
1532-
protected def subPatRefs(binder: Symbol, subpatBinders: List[Symbol], binderTypeTested: Type): List[Tree] = {
1495+
private def subPatRefs(binder: Symbol, subpatBinders: List[Symbol], binderTypeTested: Type): List[Tree] = {
15331496
if (aligner.isSingle && aligner.extractor.prodArity == 1 && defn.isTupleType(binder.info)) {
15341497
// special case for extractor
15351498
// comparing with scalac additional assertions added
15361499
val subpw = subpatBinders.head.info.widen
15371500
val binderw = binder.info.widen
15381501
val go = subpatBinders.head.info <:< binder.info
15391502
val go1 = binder.info <:< subpatBinders.head.info
1540-
//val spr = subPatRefs(binder)
15411503
assert(go && go1)
15421504
ref(binder) :: Nil
15431505
}
@@ -1547,27 +1509,6 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
15471509
else
15481510
subPatRefs(binder)
15491511
}
1550-
1551-
/*protected def spliceApply(binder: Symbol): Tree = {
1552-
object splice extends TreeMap {
1553-
def binderRef(pos: Position): Tree =
1554-
ref(binder) //setPos pos
1555-
1556-
override def transform(t: tpd.Tree)(implicit ctx: Context): tpd.Tree = t match {
1557-
// duplicated with the extractor Unapplied
1558-
case Apply(x, List(i @ Ident(nme.SELECTOR_DUMMY))) =>
1559-
cpy.Apply(t, x, binderRef(i.pos) :: Nil)
1560-
// SI-7868 Account for numeric widening, e.g. <unappplySelector>.toInt
1561-
case Apply(x, List(i @ (sel @ Select(Ident(nme.SELECTOR_DUMMY), name)))) =>
1562-
cpy.Apply(t, x, cpy.Select(sel, binderRef(i.pos), name) :: Nil)
1563-
case _ =>
1564-
super.transform(t)
1565-
}
1566-
}
1567-
splice transform extractorCallIncludingDummy
1568-
}*/
1569-
1570-
override def rawSubPatTypes = aligner.extractor.varargsTypes
15711512
}
15721513
}
15731514

0 commit comments

Comments
 (0)