Skip to content

Commit 2bb7d53

Browse files
committed
Dealias type bindings in inlined expansions
1 parent 4bab817 commit 2bb7d53

File tree

1 file changed

+50
-5
lines changed

1 file changed

+50
-5
lines changed

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)