@@ -834,6 +834,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
834834 def dropUnusedDefs (bindings : List [MemberDef ], tree : Tree )(implicit ctx : Context ): (List [MemberDef ], Tree ) = {
835835 val refCount = newMutableSymbolMap[Int ]
836836 val bindingOfSym = newMutableSymbolMap[MemberDef ]
837+ val dealiased = new java.util.IdentityHashMap [Type , Type ]()
838+
837839 def isInlineable (binding : MemberDef ) = binding match {
838840 case DefDef (_, Nil , Nil , _, _) => true
839841 case vdef @ ValDef (_, _, _) => isPureExpr(vdef.rhs)
@@ -843,6 +845,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
843845 refCount(binding.symbol) = 0
844846 bindingOfSym(binding.symbol) = binding
845847 }
848+
846849 val countRefs = new TreeTraverser {
847850 override def traverse (t : Tree )(implicit ctx : Context ) = {
848851 def updateRefCount (sym : Symbol , inc : Int ) =
@@ -868,7 +871,45 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
868871 case none => true
869872 }
870873 } && ! boundSym.is(TransparentImplicitMethod )
871- // FIXME: It would be nice if we could also drop type bindings, but reference counting is trickier for them.
874+
875+ val (termBindings, typeBindings) = bindings.partition(_.symbol.isTerm)
876+
877+ /** drop any referenced type symbols from the given set of type symbols */
878+ val dealiasTypeBindings = new TreeMap {
879+ val boundTypes = typeBindings.map(_.symbol).toSet
880+
881+ val dealias = new TypeMap {
882+ override def apply (tp : Type ) = dealiased.get(tp) match {
883+ case null =>
884+ val tp1 = mapOver {
885+ tp match {
886+ case tp : TypeRef if boundTypes.contains(tp.symbol) =>
887+ val TypeAlias (alias) = tp.info
888+ alias
889+ case _ => tp
890+ }
891+ }
892+ dealiased.put(tp, tp1)
893+ tp1
894+ case tp1 => tp1
895+ }
896+ }
897+
898+ override def transform (t : Tree )(implicit ctx : Context ) = {
899+ val dealiasedType = dealias(t.tpe)
900+ val t1 = t match {
901+ case t : RefTree =>
902+ if (boundTypes.contains(t.symbol)) TypeTree (dealiasedType).withPos(t.pos)
903+ else t.withType(dealiasedType)
904+ case t : DefTree =>
905+ t.symbol.info = dealias(t.symbol.info)
906+ t
907+ case _ =>
908+ t.withType(dealiasedType)
909+ }
910+ super .transform(t1)
911+ }
912+ }
872913
873914 val inlineBindings = new TreeMap {
874915 override def transform (t : Tree )(implicit ctx : Context ) = t match {
@@ -892,12 +933,16 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
892933 }
893934 }
894935
895- val retained = bindings.filterConserve(binding => retain(binding.symbol))
896- if (retained `eq` bindings) {
897- (bindings, tree)
936+ val dealiasedTermBindings =
937+ termBindings.mapconserve(dealiasTypeBindings.transform).asInstanceOf [List [MemberDef ]]
938+ val dealiasedTree = dealiasTypeBindings.transform(tree)
939+
940+ val retained = dealiasedTermBindings.filterConserve(binding => retain(binding.symbol))
941+ if (retained `eq` dealiasedTermBindings) {
942+ (dealiasedTermBindings, dealiasedTree)
898943 }
899944 else {
900- val expanded = inlineBindings.transform(tree )
945+ val expanded = inlineBindings.transform(dealiasedTree )
901946 dropUnusedDefs(retained, expanded)
902947 }
903948 }
0 commit comments