@@ -670,59 +670,6 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
670
670
override def toString = " X" + ((extractor, nextBinder.name))
671
671
}
672
672
673
- /**
674
- * An optimized version of ExtractorTreeMaker for Products.
675
- * For now, this is hard-coded to case classes, and we simply extract the case class fields.
676
- *
677
- * The values for the subpatterns, as specified by the case class fields at the time of extraction,
678
- * are stored in local variables that re-use the symbols in `subPatBinders`.
679
- * This makes extractor patterns more debuggable (SI-5739) as well as
680
- * avoiding mutation after the pattern has been matched (SI-5158, SI-6070)
681
- *
682
- * TODO: make this user-definable as follows
683
- * When a companion object defines a method `def unapply_1(x: T): U_1`, but no `def unapply` or `def unapplySeq`,
684
- * the extractor is considered to match any non-null value of type T
685
- * the pattern is expected to have as many sub-patterns as there are `def unapply_I(x: T): U_I` methods,
686
- * and the type of the I'th sub-pattern is `U_I`.
687
- * The same exception for Seq patterns applies: if the last extractor is of type `Seq[U_N]`,
688
- * the pattern must have at least N arguments (exactly N if the last argument is annotated with `: _*`).
689
- * The arguments starting at N (and beyond) are taken from the sequence returned by apply_N,
690
- * and it is checked that the sequence has enough elements to provide values for all expected sub-patterns.
691
- *
692
- * For a case class C, the implementation is assumed to be `def unapply_I(x: C) = x._I`,
693
- * and the extractor call is inlined under that assumption.
694
- */
695
- case class ProductExtractorTreeMaker (prevBinder : Symbol , extraCond : Option [Tree ])(
696
- val subPatBinders : List [Symbol ],
697
- val subPatRefs : List [Tree ],
698
- val mutableBinders : List [Symbol ],
699
- binderKnownNonNull : Boolean ,
700
- val ignoredSubPatBinders : Set [Symbol ]
701
- ) extends FunTreeMaker with PreserveSubPatBinders {
702
-
703
- val nextBinder = prevBinder // just passing through
704
-
705
- // mutable binders must be stored to avoid unsoundness or seeing mutation of fields after matching (SI-5158, SI-6070)
706
- def extraStoredBinders : Set [Symbol ] = mutableBinders.toSet
707
-
708
- def chainBefore (next : Tree )(casegen : Casegen ): Tree = {
709
- val nullCheck : Tree = ref(prevBinder).select(defn.Object_ne ).appliedTo(Literal (Constant (null )))
710
-
711
- val cond : Option [Tree ] =
712
- if (binderKnownNonNull) extraCond
713
- else extraCond.map(nullCheck.select(defn.Boolean_&& ).appliedTo).orElse(Some (nullCheck))
714
-
715
- cond match {
716
- case Some (cond : Tree ) =>
717
- casegen.ifThenElseZero(cond, bindSubPats(next))
718
- case _ =>
719
- bindSubPats(next)
720
- }
721
- }
722
-
723
- override def toString = " P" + ((prevBinder.name, extraCond getOrElse " " , introducedRebindings))
724
- }
725
-
726
673
object IrrefutableExtractorTreeMaker {
727
674
// will an extractor with unapply method of methodtype `tp` always succeed?
728
675
// note: this assumes the other side-conditions implied by the extractor are met
@@ -1392,15 +1339,11 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
1392
1339
// TODO: check unargs == args
1393
1340
def apply (tree : Tree , binder : Symbol ): ExtractorCall = {
1394
1341
tree match {
1342
+ case Typed (unapply, _) => apply(unapply, binder)
1395
1343
case UnApply (unfun, implicits, args) =>
1396
1344
val castedBinder = ref(binder).ensureConforms(tree.tpe)
1397
1345
val synth = if (implicits.isEmpty) unfun.appliedTo(castedBinder) else unfun.appliedTo(castedBinder).appliedToArgs(implicits)
1398
- new ExtractorCallRegular (alignPatterns(tree, synth.tpe), synth, args, synth.tpe) // extractor
1399
- case Typed (unapply@ UnApply (unfun, implicits, args), tpt) =>
1400
- val castedBinder = ref(binder).ensureConforms(unapply.tpe)
1401
- val synth = /* Typed(*/ if (implicits.isEmpty) unfun.appliedTo(castedBinder) else unfun.appliedTo(castedBinder).appliedToArgs(implicits) // , tpt)
1402
- new ExtractorCallRegular (alignPatterns(tree, synth.tpe), synth, args, synth.tpe) // extractor
1403
- case Apply (fun, args) => new ExtractorCallProd (alignPatterns(tree, tree.tpe), fun, args, fun.tpe) // case class
1346
+ new ExtractorCallRegular (alignPatterns(tree, synth.tpe), synth, args, synth.tpe)
1404
1347
}
1405
1348
}
1406
1349
}
@@ -1544,34 +1487,6 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
1544
1487
else Some (expectedLength)
1545
1488
}
1546
1489
1547
- // TODO: to be called when there's a def unapplyProd(x: T): U
1548
- // U must have N members _1,..., _N -- the _i are type checked, call their type Ti,
1549
- // for now only used for case classes -- pretending there's an unapplyProd that's the identity (and don't call it)
1550
- class ExtractorCallProd (aligner : PatternAligned , val fun : Tree , val args : List [Tree ], val resultType : Type ) extends ExtractorCall (aligner) {
1551
- /** Create the TreeMaker that embodies this extractor call
1552
- *
1553
- * `binder` has been casted to `paramType` if necessary
1554
- * `binderKnownNonNull` indicates whether the cast implies `binder` cannot be null
1555
- * when `binderKnownNonNull` is `true`, `ProductExtractorTreeMaker` does not do a (redundant) null check on binder
1556
- */
1557
- def treeMaker (binder : Symbol , binderKnownNonNull : Boolean , pos : Position , binderTypeTested : Type ): TreeMaker = {
1558
- val paramAccessors = binder.caseAccessors
1559
- // binders corresponding to mutable fields should be stored (SI-5158, SI-6070)
1560
- // make an exception for classes under the scala package as they should be well-behaved,
1561
- // to optimize matching on List
1562
- val mutableBinders = (
1563
- if (// !binder.info.typeSymbol.hasTransOwner(ScalaPackageClass) // TODO: DDD ???
1564
- // &&
1565
- (paramAccessors exists (_.hasAltWith(x => x.symbol is Flags .Mutable ))))
1566
- subPatBinders.zipWithIndex.collect{ case (binder, idx) if paramAccessors(idx).hasAltWith(x => x.symbol is Flags .Mutable ) => binder }
1567
- else Nil
1568
- )
1569
-
1570
- // checks binder ne null before chaining to the next extractor
1571
- ProductExtractorTreeMaker (binder, lengthGuard(binder))(subPatBinders, subPatRefs(binder), mutableBinders, binderKnownNonNull, ignoredSubPatBinders)
1572
- }
1573
- }
1574
-
1575
1490
class ExtractorCallRegular (aligner : PatternAligned , extractorCallIncludingDummy : Tree , val args : List [Tree ], val resultType : Type ) extends ExtractorCall (aligner) {
1576
1491
1577
1492
/** Create the TreeMaker that embodies this extractor call
@@ -1893,11 +1808,6 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
1893
1808
}
1894
1809
1895
1810
object alignPatterns extends ScalacPatternExpander {
1896
- /** Converts a T => (A, B, C) extractor to a T => ((A, B, CC)) extractor.
1897
- */
1898
- def tupleExtractor (extractor : Extractor ): Extractor =
1899
- extractor.copy(fixed = defn.tupleType(extractor.fixed) :: Nil )
1900
-
1901
1811
private def validateAligned (tree : Tree , aligned : Aligned ): Aligned = {
1902
1812
import aligned ._
1903
1813
@@ -1939,29 +1849,13 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
1939
1849
}
1940
1850
val patterns = newPatterns(args)
1941
1851
val isSeq = sel.symbol.name == nme.unapplySeq
1942
- val isUnapply = sel.symbol.name == nme.unapply
1943
1852
val extractor = sel.symbol.name match {
1944
1853
case nme.unapply => unapplyMethodTypes(tree, /* fn*/ sel, args, resultType, isSeq = false )
1945
1854
case nme.unapplySeq => unapplyMethodTypes(tree, /* fn*/ sel, args, resultType, isSeq = true )
1946
1855
case _ => applyMethodTypes(/* fn*/ sel.tpe)
1947
1856
}
1948
1857
1949
- /** Rather than let the error that is SI-6675 pollute the entire matching
1950
- * process, we will tuple the extractor before creation Aligned so that
1951
- * it contains known good values.
1952
- */
1953
- def prodArity = extractor.prodArity
1954
- def acceptMessage = if (extractor.isErroneous) " " else s " to hold ${extractor.offeringString}"
1955
- val requiresTupling = isUnapply && patterns.totalArity == 1 && prodArity > 1
1956
-
1957
- // if (requiresTupling && effectivePatternArity(args) == 1)
1958
- // currentUnit.deprecationWarning(sel.pos, s"${sel.symbol.owner} expects $prodArity patterns$acceptMessage but crushing into $prodArity-tuple to fit single pattern (SI-6675)")
1959
-
1960
- val normalizedExtractor =
1961
- if (requiresTupling)
1962
- tupleExtractor(extractor)
1963
- else extractor
1964
- validateAligned(fn, Aligned (patterns, normalizedExtractor))
1858
+ validateAligned(fn, Aligned (patterns, extractor))
1965
1859
}
1966
1860
1967
1861
def apply (tree : Tree , resultType : Type ): Aligned = tree match {
0 commit comments