@@ -834,6 +834,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
834
834
def dropUnusedDefs (bindings : List [MemberDef ], tree : Tree )(implicit ctx : Context ): (List [MemberDef ], Tree ) = {
835
835
val refCount = newMutableSymbolMap[Int ]
836
836
val bindingOfSym = newMutableSymbolMap[MemberDef ]
837
+ val dealiased = new java.util.IdentityHashMap [Type , Type ]()
838
+
837
839
def isInlineable (binding : MemberDef ) = binding match {
838
840
case DefDef (_, Nil , Nil , _, _) => true
839
841
case vdef @ ValDef (_, _, _) => isPureExpr(vdef.rhs)
@@ -843,6 +845,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
843
845
refCount(binding.symbol) = 0
844
846
bindingOfSym(binding.symbol) = binding
845
847
}
848
+
846
849
val countRefs = new TreeTraverser {
847
850
override def traverse (t : Tree )(implicit ctx : Context ) = {
848
851
def updateRefCount (sym : Symbol , inc : Int ) =
@@ -868,7 +871,45 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
868
871
case none => true
869
872
}
870
873
} && ! 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
+ }
872
913
873
914
val inlineBindings = new TreeMap {
874
915
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) {
892
933
}
893
934
}
894
935
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)
898
943
}
899
944
else {
900
- val expanded = inlineBindings.transform(tree )
945
+ val expanded = inlineBindings.transform(dealiasedTree )
901
946
dropUnusedDefs(retained, expanded)
902
947
}
903
948
}
0 commit comments