@@ -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
@@ -1397,15 +1344,11 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
1397
1344
// TODO: check unargs == args
1398
1345
def apply (tree : Tree , binder : Symbol ): ExtractorCall = {
1399
1346
tree match {
1347
+ case Typed (unapply, _) => apply(unapply, binder)
1400
1348
case UnApply (unfun, implicits, args) =>
1401
1349
val castedBinder = ref(binder).ensureConforms(tree.tpe)
1402
1350
val synth = if (implicits.isEmpty) unfun.appliedTo(castedBinder) else unfun.appliedTo(castedBinder).appliedToArgs(implicits)
1403
- new ExtractorCallRegular (alignPatterns(tree, synth.tpe), synth, args, synth.tpe) // extractor
1404
- case Typed (unapply@ UnApply (unfun, implicits, args), tpt) =>
1405
- val castedBinder = ref(binder).ensureConforms(unapply.tpe)
1406
- val synth = /* Typed(*/ if (implicits.isEmpty) unfun.appliedTo(castedBinder) else unfun.appliedTo(castedBinder).appliedToArgs(implicits) // , tpt)
1407
- new ExtractorCallRegular (alignPatterns(tree, synth.tpe), synth, args, synth.tpe) // extractor
1408
- case Apply (fun, args) => new ExtractorCallProd (alignPatterns(tree, tree.tpe), fun, args, fun.tpe) // case class
1351
+ new ExtractorCallRegular (alignPatterns(tree, synth.tpe), synth, args, synth.tpe)
1409
1352
}
1410
1353
}
1411
1354
}
@@ -1549,34 +1492,6 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
1549
1492
else Some (expectedLength)
1550
1493
}
1551
1494
1552
- // TODO: to be called when there's a def unapplyProd(x: T): U
1553
- // U must have N members _1,..., _N -- the _i are type checked, call their type Ti,
1554
- // for now only used for case classes -- pretending there's an unapplyProd that's the identity (and don't call it)
1555
- class ExtractorCallProd (aligner : PatternAligned , val fun : Tree , val args : List [Tree ], val resultType : Type ) extends ExtractorCall (aligner) {
1556
- /** Create the TreeMaker that embodies this extractor call
1557
- *
1558
- * `binder` has been casted to `paramType` if necessary
1559
- * `binderKnownNonNull` indicates whether the cast implies `binder` cannot be null
1560
- * when `binderKnownNonNull` is `true`, `ProductExtractorTreeMaker` does not do a (redundant) null check on binder
1561
- */
1562
- def treeMaker (binder : Symbol , binderKnownNonNull : Boolean , pos : Position , binderTypeTested : Type ): TreeMaker = {
1563
- val paramAccessors = binder.caseAccessors
1564
- // binders corresponding to mutable fields should be stored (SI-5158, SI-6070)
1565
- // make an exception for classes under the scala package as they should be well-behaved,
1566
- // to optimize matching on List
1567
- val mutableBinders = (
1568
- if (// !binder.info.typeSymbol.hasTransOwner(ScalaPackageClass) // TODO: DDD ???
1569
- // &&
1570
- (paramAccessors exists (_.hasAltWith(x => x.symbol is Flags .Mutable ))))
1571
- subPatBinders.zipWithIndex.collect{ case (binder, idx) if paramAccessors(idx).hasAltWith(x => x.symbol is Flags .Mutable ) => binder }
1572
- else Nil
1573
- )
1574
-
1575
- // checks binder ne null before chaining to the next extractor
1576
- ProductExtractorTreeMaker (binder, lengthGuard(binder))(subPatBinders, subPatRefs(binder), mutableBinders, binderKnownNonNull, ignoredSubPatBinders)
1577
- }
1578
- }
1579
-
1580
1495
class ExtractorCallRegular (aligner : PatternAligned , extractorCallIncludingDummy : Tree , val args : List [Tree ], val resultType : Type ) extends ExtractorCall (aligner) {
1581
1496
1582
1497
/** Create the TreeMaker that embodies this extractor call
0 commit comments