@@ -20,7 +20,7 @@ import SymDenotations.SymDenotation
20
20
import Inferencing .fullyDefinedType
21
21
import config .Printers .inlining
22
22
import ErrorReporting .errorTree
23
- import dotty .tools .dotc .util .SimpleIdentitySet
23
+ import dotty .tools .dotc .util .{ SimpleIdentityMap , SimpleIdentitySet }
24
24
25
25
import collection .mutable
26
26
import reporting .trace
@@ -719,16 +719,9 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
719
719
}
720
720
}
721
721
722
- def getBoundVarsList (pat : Tree , tpt : Tree ): List [(TypeSymbol , Boolean )] = {
723
- // UnApply nodes with pattern bound variables translate to something like this
724
- // UnApply[t @ t](pats)(implicits): T[t]
725
- // Need to traverse any binds in type arguments of the UnAppyl to get the set of
726
- // all instantiable type variables. Test case is pos/inline-caseclass.scala.
727
- val allTpts = tpt :: (pat match {
728
- case UnApply (TypeApply (_, tpts), _, _) => tpts
729
- case _ => Nil
730
- })
722
+ type TypeBindsMap = SimpleIdentityMap [TypeSymbol , java.lang.Boolean ]
731
723
724
+ def getTypeBindsMap (pat : Tree , tpt : Tree ): TypeBindsMap = {
732
725
val getBinds = new TreeAccumulator [Set [TypeSymbol ]] {
733
726
def apply (syms : Set [TypeSymbol ], t : Tree )(implicit ctx : Context ): Set [TypeSymbol ] = {
734
727
val syms1 = t match {
@@ -739,48 +732,65 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
739
732
foldOver(syms1, t)
740
733
}
741
734
}
742
- val binds = allTpts.foldLeft[Set [TypeSymbol ]](Set .empty)(getBinds.apply(_, _))
743
- val findBoundVars = new TypeAccumulator [List [(TypeSymbol , Boolean )]] {
744
- def apply (syms : List [(TypeSymbol , Boolean )], t : Type ) = {
735
+
736
+ // Extractors contain Bind nodes in type parameter lists, the tree looks like this:
737
+ // UnApply[t @ t](pats)(implicits): T[t]
738
+ // Test case is pos/inline-caseclass.scala.
739
+ val binds : Set [TypeSymbol ] = pat match {
740
+ case UnApply (TypeApply (_, tpts), _, _) => getBinds(Set .empty[TypeSymbol ], tpts)
741
+ case _ => getBinds(Set .empty[TypeSymbol ], tpt)
742
+ }
743
+
744
+ val extractBindVariance = new TypeAccumulator [TypeBindsMap ] {
745
+ def apply (syms : TypeBindsMap , t : Type ) = {
745
746
val syms1 = t match {
746
- case tr : TypeRef if tr.symbol.is(Case ) && binds.contains(tr.symbol.asType) =>
747
- (tr.typeSymbol.asType, variance >= 0 ) :: syms
747
+ // `binds` is used to check if the symbol was actually bound by the pattern we're processing
748
+ case tr : TypeRef if tr.symbol.is(Case ) && binds.contains(tr.symbol.asType) =>
749
+ val trSym = tr.symbol.asType
750
+ // Exact same logic as in IsFullyDefinedAccumulator:
751
+ // the binding is to be maximized iff it only occurs contravariantly in the type
752
+ val wasToBeMinimized : Boolean = {
753
+ val v = syms(trSym)
754
+ if (v ne null ) v else false
755
+ }
756
+ syms.updated(trSym, wasToBeMinimized || variance >= 0 : java.lang.Boolean )
748
757
case _ =>
749
758
syms
750
759
}
751
760
foldOver(syms1, t)
752
761
}
753
762
}
754
- findBoundVars(Nil , tpt.tpe)
763
+
764
+ extractBindVariance(SimpleIdentityMap .Empty , tpt.tpe)
755
765
}
756
766
757
- def registerAsGadtSyms (list : List [( TypeSymbol , Boolean )] )(implicit ctx : Context ): Unit =
758
- list.foreach { case (sym, _) =>
767
+ def registerAsGadtSyms (typeBinds : TypeBindsMap )(implicit ctx : Context ): Unit =
768
+ typeBinds.foreachBinding { case (sym, _) =>
759
769
val TypeBounds (lo, hi) = sym.info.bounds
760
770
ctx.gadt.addBound(sym, lo, isUpper = false )
761
771
ctx.gadt.addBound(sym, hi, isUpper = true )
762
772
}
763
773
764
- def addTypeBindings (list : List [( TypeSymbol , Boolean )] )(implicit ctx : Context ): Unit =
765
- list.foreach { case (sym, fromBelow ) =>
766
- val copied = sym.copy(info = TypeAlias (ctx.gadt.approximation(sym, fromBelow = fromBelow ))).asType
774
+ def addTypeBindings (typeBinds : TypeBindsMap )(implicit ctx : Context ): Unit =
775
+ typeBinds.foreachBinding { case (sym, shouldBeMinimized ) =>
776
+ val copied = sym.copy(info = TypeAlias (ctx.gadt.approximation(sym, fromBelow = shouldBeMinimized ))).asType
767
777
fromBuf += sym
768
778
toBuf += copied
769
779
}
770
780
771
781
pat match {
772
782
case Typed (pat1, tpt) =>
773
- val boundVars = getBoundVarsList (pat1, tpt)
774
- registerAsGadtSyms(boundVars )
783
+ val typeBinds = getTypeBindsMap (pat1, tpt)
784
+ registerAsGadtSyms(typeBinds )
775
785
scrut <:< tpt.tpe && {
776
- addTypeBindings(boundVars )
786
+ addTypeBindings(typeBinds )
777
787
reducePattern(bindingsBuf, fromBuf, toBuf, scrut, pat1)
778
788
}
779
789
case pat @ Bind (name : TermName , Typed (_, tpt)) if isImplicit =>
780
- val boundVars = getBoundVarsList (tpt, tpt)
781
- registerAsGadtSyms(boundVars )
790
+ val typeBinds = getTypeBindsMap (tpt, tpt)
791
+ registerAsGadtSyms(typeBinds )
782
792
searchImplicit(pat.symbol.asTerm, tpt) && {
783
- addTypeBindings(boundVars )
793
+ addTypeBindings(typeBinds )
784
794
true
785
795
}
786
796
case pat @ Bind (name : TermName , body) =>
@@ -990,7 +1000,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
990
1000
def dropUnusedDefs (bindings : List [MemberDef ], tree : Tree )(implicit ctx : Context ): (List [MemberDef ], Tree ) = {
991
1001
// inlining.println(i"drop unused $bindings%, % in $tree")
992
1002
993
- def go (termBindings : List [MemberDef ], tree : Tree )(implicit ctx : Context ): (List [MemberDef ], Tree ) = {
1003
+ def inlineTermBindings (termBindings : List [MemberDef ], tree : Tree )(implicit ctx : Context ): (List [MemberDef ], Tree ) = {
994
1004
val refCount = newMutableSymbolMap[Int ]
995
1005
val bindingOfSym = newMutableSymbolMap[MemberDef ]
996
1006
@@ -1068,17 +1078,15 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
1068
1078
}
1069
1079
1070
1080
val (termBindings, typeBindings) = bindings.partition(_.symbol.isTerm)
1071
- if (typeBindings.isEmpty) go (termBindings, tree)
1081
+ if (typeBindings.isEmpty) inlineTermBindings (termBindings, tree)
1072
1082
else {
1073
1083
val typeBindingsSet = typeBindings.foldLeft[SimpleIdentitySet [Symbol ]](SimpleIdentitySet .empty)(_ + _.symbol)
1074
- val ttm = new TreeTypeMap (
1084
+ val inlineTypeBindings = new TreeTypeMap (
1075
1085
typeMap = new TypeMap () {
1076
1086
override def apply (tp : Type ): Type = tp match {
1077
- case tr : TypeRef if tr.prefix eq NoPrefix =>
1078
- if (typeBindingsSet.contains(tr.symbol)) {
1079
- val TypeAlias (res) = tr.info
1080
- res
1081
- } else tr
1087
+ case tr : TypeRef if tr.prefix.eq(NoPrefix ) && typeBindingsSet.contains(tr.symbol) =>
1088
+ val TypeAlias (res) = tr.info
1089
+ res
1082
1090
case tp => mapOver(tp)
1083
1091
}
1084
1092
},
@@ -1090,8 +1098,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
1090
1098
}
1091
1099
)
1092
1100
1093
- val Block (termBindings1, tree1) = ttm (Block (termBindings, tree))
1094
- go (termBindings1.asInstanceOf [List [MemberDef ]], tree1)
1101
+ val Block (termBindings1, tree1) = inlineTypeBindings (Block (termBindings, tree))
1102
+ inlineTermBindings (termBindings1.asInstanceOf [List [MemberDef ]], tree1)
1095
1103
}
1096
1104
}
1097
1105
}
0 commit comments