@@ -20,7 +20,7 @@ import SymDenotations.SymDenotation
2020import Inferencing .fullyDefinedType
2121import config .Printers .inlining
2222import ErrorReporting .errorTree
23- import dotty .tools .dotc .util .SimpleIdentitySet
23+ import dotty .tools .dotc .util .{ SimpleIdentityMap , SimpleIdentitySet }
2424
2525import collection .mutable
2626import reporting .trace
@@ -719,16 +719,9 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
719719 }
720720 }
721721
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 ]
731723
724+ def getTypeBindsMap (pat : Tree , tpt : Tree ): TypeBindsMap = {
732725 val getBinds = new TreeAccumulator [Set [TypeSymbol ]] {
733726 def apply (syms : Set [TypeSymbol ], t : Tree )(implicit ctx : Context ): Set [TypeSymbol ] = {
734727 val syms1 = t match {
@@ -739,48 +732,65 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
739732 foldOver(syms1, t)
740733 }
741734 }
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 ) = {
745746 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 )
748757 case _ =>
749758 syms
750759 }
751760 foldOver(syms1, t)
752761 }
753762 }
754- findBoundVars(Nil , tpt.tpe)
763+
764+ extractBindVariance(SimpleIdentityMap .Empty , tpt.tpe)
755765 }
756766
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, _) =>
759769 val TypeBounds (lo, hi) = sym.info.bounds
760770 ctx.gadt.addBound(sym, lo, isUpper = false )
761771 ctx.gadt.addBound(sym, hi, isUpper = true )
762772 }
763773
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
767777 fromBuf += sym
768778 toBuf += copied
769779 }
770780
771781 pat match {
772782 case Typed (pat1, tpt) =>
773- val boundVars = getBoundVarsList (pat1, tpt)
774- registerAsGadtSyms(boundVars )
783+ val typeBinds = getTypeBindsMap (pat1, tpt)
784+ registerAsGadtSyms(typeBinds )
775785 scrut <:< tpt.tpe && {
776- addTypeBindings(boundVars )
786+ addTypeBindings(typeBinds )
777787 reducePattern(bindingsBuf, fromBuf, toBuf, scrut, pat1)
778788 }
779789 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 )
782792 searchImplicit(pat.symbol.asTerm, tpt) && {
783- addTypeBindings(boundVars )
793+ addTypeBindings(typeBinds )
784794 true
785795 }
786796 case pat @ Bind (name : TermName , body) =>
@@ -990,7 +1000,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
9901000 def dropUnusedDefs (bindings : List [MemberDef ], tree : Tree )(implicit ctx : Context ): (List [MemberDef ], Tree ) = {
9911001 // inlining.println(i"drop unused $bindings%, % in $tree")
9921002
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 ) = {
9941004 val refCount = newMutableSymbolMap[Int ]
9951005 val bindingOfSym = newMutableSymbolMap[MemberDef ]
9961006
@@ -1068,17 +1078,15 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
10681078 }
10691079
10701080 val (termBindings, typeBindings) = bindings.partition(_.symbol.isTerm)
1071- if (typeBindings.isEmpty) go (termBindings, tree)
1081+ if (typeBindings.isEmpty) inlineTermBindings (termBindings, tree)
10721082 else {
10731083 val typeBindingsSet = typeBindings.foldLeft[SimpleIdentitySet [Symbol ]](SimpleIdentitySet .empty)(_ + _.symbol)
1074- val ttm = new TreeTypeMap (
1084+ val inlineTypeBindings = new TreeTypeMap (
10751085 typeMap = new TypeMap () {
10761086 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
10821090 case tp => mapOver(tp)
10831091 }
10841092 },
@@ -1090,8 +1098,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
10901098 }
10911099 )
10921100
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)
10951103 }
10961104 }
10971105}
0 commit comments