Skip to content

Commit aa014d4

Browse files
committed
Address review comments
1 parent bd81a2f commit aa014d4

File tree

2 files changed

+47
-38
lines changed

2 files changed

+47
-38
lines changed

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

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import SymDenotations.SymDenotation
2020
import Inferencing.fullyDefinedType
2121
import config.Printers.inlining
2222
import ErrorReporting.errorTree
23-
import dotty.tools.dotc.util.SimpleIdentitySet
23+
import dotty.tools.dotc.util.{SimpleIdentityMap, SimpleIdentitySet}
2424

2525
import collection.mutable
2626
import 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
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,8 @@ object ProtoTypes {
573573
*/
574574
private def wildApprox(tp: Type, theMap: WildApproxMap, seen: Set[TypeParamRef])(implicit ctx: Context): Type = tp match {
575575
case tp: NamedType => // default case, inlined for speed
576-
if (tp.isInstanceOf[TypeRef] && tp.symbol.is(Flags.Case) && !tp.symbol.isClass) WildcardType(tp.underlying.bounds)
576+
val isPatternBoundTypeRef = tp.isInstanceOf[TypeRef] && tp.symbol.is(Flags.Case) && !tp.symbol.isClass
577+
if (isPatternBoundTypeRef) WildcardType(tp.underlying.bounds)
577578
else if (tp.symbol.isStatic || (tp.prefix `eq` NoPrefix)) tp
578579
else tp.derivedSelect(wildApprox(tp.prefix, theMap, seen))
579580
case tp @ AppliedType(tycon, args) =>

0 commit comments

Comments
 (0)