Skip to content

Commit b27e78d

Browse files
author
Aleksander Boruch-Gruszecki
committed
Revert "Parameterize Constraint with constrained VarRef"
This reverts commit 4845d42.
1 parent b05630b commit b27e78d

10 files changed

+153
-256
lines changed

compiler/src/dotty/tools/dotc/core/Constraint.scala

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ package core
55
import Types._, Contexts._
66
import printing.Showable
77

8+
object Constraint {
9+
type VarRef = TypeVarRef
10+
type Binder = TypeVarRefBinder
11+
}
12+
813
/** Constraint over undetermined type parameters. Constraints are built
914
* over values of the following types:
1015
*
@@ -13,17 +18,19 @@ import printing.Showable
1318
* - TypeVar Every constrained parameter might be associated with a TypeVar
1419
* that has the TypeParamRef as origin.
1520
*/
16-
abstract class Constraint[VarRef <: TypeVarRef, RefBinder <: TypeVarRefBinder] extends Showable {
17-
type This <: Constraint[VarRef, RefBinder]
21+
abstract class Constraint extends Showable {
22+
import Constraint._
23+
24+
type This <: Constraint
1825

1926
/** Does the constraint's domain contain the type parameters of `pt`? */
20-
def contains(pt: RefBinder): Boolean
27+
def contains(pt: Binder): Boolean
2128

2229
/** Does the constraint's domain contain the type parameter `param`? */
2330
def contains(param: VarRef): Boolean
2431

2532
/** Does this constraint contain the type variable `tvar` and is it uninstantiated? */
26-
def contains(tvar: TypeVarHandle[VarRef]): Boolean
33+
def contains(tvar: TypeVar): Boolean
2734

2835
/** The constraint entry for given type parameter `param`, or NoType if `param` is not part of
2936
* the constraint domain. Note: Low level, implementation dependent.
@@ -73,7 +80,7 @@ abstract class Constraint[VarRef <: TypeVarRef, RefBinder <: TypeVarRefBinder] e
7380
* satisfiability but will solved to give instances of
7481
* type variables.
7582
*/
76-
def add(poly: RefBinder, tvars: List[TypeVarHandle[VarRef]])(implicit ctx: Context): This
83+
def add(poly: Binder, tvars: List[TypeVar])(implicit ctx: Context): This
7784

7885
/** A new constraint which is derived from this constraint by updating
7986
* the entry for parameter `param` to `tp`.
@@ -109,13 +116,13 @@ abstract class Constraint[VarRef <: TypeVarRef, RefBinder <: TypeVarRefBinder] e
109116
* all type parameters of the entry are associated with type variables
110117
* which have their `inst` fields set.
111118
*/
112-
def isRemovable(pt: RefBinder): Boolean
119+
def isRemovable(pt: Binder): Boolean
113120

114121
/** A new constraint with all entries coming from `pt` removed. */
115-
def remove(pt: RefBinder)(implicit ctx: Context): This
122+
def remove(pt: Binder)(implicit ctx: Context): This
116123

117124
/** The type lambdas constrained by this constraint */
118-
def domainLambdas: List[RefBinder]
125+
def domainLambdas: List[Binder]
119126

120127
/** The type lambda parameters constrained by this constraint */
121128
def domainParams: List[VarRef]
@@ -136,7 +143,7 @@ abstract class Constraint[VarRef <: TypeVarRef, RefBinder <: TypeVarRefBinder] e
136143
* returning an approximate constraint, instead of
137144
* failing with an exception
138145
*/
139-
def & (other: Constraint[VarRef, RefBinder], otherHasErrors: Boolean)(implicit ctx: Context): Constraint[VarRef, RefBinder]
146+
def & (other: Constraint, otherHasErrors: Boolean)(implicit ctx: Context): Constraint
140147

141148
/** Check that no constrained parameter contains itself as a bound */
142149
def checkNonCyclic()(implicit ctx: Context): Unit

compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,19 @@ import config.Printers.{constr, typr}
1818
* By comparison: Constraint handlers are parts of type comparers and can use their functionality.
1919
* Constraint handlers update the current constraint as a side effect.
2020
*/
21-
trait ConstraintHandling[VarRef <: TypeVarRef.Of[VarRef, RefBinder], RefBinder <: TypeVarRefBinder.Of[VarRef, RefBinder]] {
22-
protected final type OwnConstraint = Constraint[VarRef, RefBinder]
21+
trait ConstraintHandling {
22+
import Constraint._
2323

24-
protected def isVarRef(r: Type): Boolean = r.isInstanceOf[TypeVarRef]
25-
protected def isRefBinder(r: Type): Boolean = r.isInstanceOf[TypeVarRefBinder]
26-
27-
protected def constr_println(msg: => String): Unit = constr.println(msg)
28-
protected def typr_println(msg: => String): Unit = typr.println(msg)
24+
def constr_println(msg: => String): Unit = constr.println(msg)
25+
def typr_println(msg: => String): Unit = typr.println(msg)
2926

3027
implicit def ctx: Context
3128

3229
protected def isSubType(tp1: Type, tp2: Type): Boolean
3330
protected def isSameType(tp1: Type, tp2: Type): Boolean
3431

35-
protected def constraint: OwnConstraint
36-
protected def constraint_=(c: OwnConstraint): Unit
32+
protected def constraint: Constraint
33+
protected def constraint_=(c: Constraint): Unit
3734

3835
private[this] var addConstraintInvocations = 0
3936

@@ -62,10 +59,9 @@ trait ConstraintHandling[VarRef <: TypeVarRef.Of[VarRef, RefBinder], RefBinder <
6259
* is done only in a temporary way for contexts that may be retracted
6360
* without also retracting the type var as a whole.
6461
*/
65-
def instType(tvar: TypeVarHandle[VarRef]): Type = constraint.entry(tvar.origin) match {
62+
def instType(tvar: TypeVar): Type = constraint.entry(tvar.origin) match {
6663
case _: TypeBounds => NoType
67-
case tp_ if isVarRef(tp_) =>
68-
val tp = tp_.asInstanceOf[VarRef]
64+
case tp: VarRef =>
6965
var tvar1 = constraint.typeVarOfParam(tp)
7066
if (tvar1.exists) tvar1 else tp
7167
case tp => tp
@@ -288,9 +284,9 @@ trait ConstraintHandling[VarRef <: TypeVarRef.Of[VarRef, RefBinder], RefBinder <
288284
case tp: SingletonType => true
289285
case AndType(tp1, tp2) => isMultiSingleton(tp1) | isMultiSingleton(tp2)
290286
case OrType(tp1, tp2) => isMultiSingleton(tp1) & isMultiSingleton(tp2)
291-
case tp_ if isVarRef(tp_) => isMultiSingleton(bounds(tp_.asInstanceOf[VarRef]).hi)
292-
case tp: TypeRef => isMultiSingleton(tp.info.hiBound)
287+
case tp: TypeRef if !constraint.contains(tp : VarRef) => isMultiSingleton(tp.info.hiBound)
293288
case tp: TypeVar => isMultiSingleton(tp.underlying)
289+
case tp: VarRef => isMultiSingleton(bounds(tp).hi)
294290
case _ => false
295291
}
296292
def isOrType(tp: Type): Boolean = tp.dealias match {
@@ -331,7 +327,7 @@ trait ConstraintHandling[VarRef <: TypeVarRef.Of[VarRef, RefBinder], RefBinder <
331327
* Both `c1` and `c2` are required to derive from constraint `pre`, possibly
332328
* narrowing it with further bounds.
333329
*/
334-
protected final def subsumes(c1: OwnConstraint, c2: OwnConstraint, pre: OwnConstraint): Boolean =
330+
protected final def subsumes(c1: Constraint, c2: Constraint, pre: Constraint): Boolean =
335331
if (c2 eq pre) true
336332
else if (c1 eq pre) false
337333
else {
@@ -359,7 +355,7 @@ trait ConstraintHandling[VarRef <: TypeVarRef.Of[VarRef, RefBinder], RefBinder <
359355
* and propagate all bounds.
360356
* @param tvars See Constraint#add
361357
*/
362-
def addToConstraint(tl: RefBinder, tvars: List[TypeVarHandle[VarRef]]): Boolean =
358+
def addToConstraint(tl: Binder, tvars: List[TypeVar]): Boolean =
363359
checkPropagated(i"initialized $tl") {
364360
constraint = constraint.add(tl, tvars)
365361
tl.boundRefs.forall { param =>
@@ -431,7 +427,7 @@ trait ConstraintHandling[VarRef <: TypeVarRef.Of[VarRef, RefBinder], RefBinder <
431427
}
432428
else tp
433429

434-
def addParamBound(bound: VarRef) =
430+
def addParamBound(bound: TypeParamRef) =
435431
constraint.entry(param) match {
436432
case _: TypeBounds =>
437433
if (fromBelow) addLess(bound, param) else addLess(param, bound)
@@ -484,10 +480,9 @@ trait ConstraintHandling[VarRef <: TypeVarRef.Of[VarRef, RefBinder], RefBinder <
484480
val p2 = prune(bound.tp2)
485481
if (p1.exists && p2.exists) bound.derivedOrType(p1, p2)
486482
else NoType
487-
case bound: TypeVar if constraint contains bound.origin.asInstanceOf[VarRef] =>
483+
case bound: TypeVar if constraint contains bound.origin =>
488484
prune(bound.underlying)
489-
case bound_ : TypeParamRef =>
490-
val bound = bound_.asInstanceOf[VarRef]
485+
case bound: TypeParamRef =>
491486
constraint.entry(bound) match {
492487
case NoType => pruneLambdaParams(bound)
493488
case _: TypeBounds =>
@@ -502,8 +497,7 @@ trait ConstraintHandling[VarRef <: TypeVarRef.Of[VarRef, RefBinder], RefBinder <
502497
}
503498

504499
try bound match {
505-
case bound_ : TypeParamRef if constraint contains bound_.asInstanceOf[VarRef] =>
506-
val bound = bound_.asInstanceOf[VarRef]
500+
case bound: TypeParamRef if constraint contains bound =>
507501
addParamBound(bound)
508502
case _ =>
509503
val pbound = prune(bound)
@@ -515,7 +509,7 @@ trait ConstraintHandling[VarRef <: TypeVarRef.Of[VarRef, RefBinder], RefBinder <
515509
}
516510

517511
/** Instantiate `param` to `tp` if the constraint stays satisfiable */
518-
protected def tryInstantiate(param: VarRef, tp: Type): Boolean = {
512+
protected def tryInstantiate(param: TypeParamRef, tp: Type): Boolean = {
519513
val saved = constraint
520514
constraint =
521515
if (addConstraint(param, tp, fromBelow = true) &&

compiler/src/dotty/tools/dotc/core/ConstraintRunInfo.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import config.Printers.{default, typr}
66

77
trait ConstraintRunInfo { self: Run =>
88
private[this] var maxSize = 0
9-
private[this] var maxConstraint: Constraint[_, _] = _
10-
def recordConstraintSize(c: Constraint[_, _], size: Int): Unit =
9+
private[this] var maxConstraint: Constraint = _
10+
def recordConstraintSize(c: Constraint, size: Int): Unit =
1111
if (size > maxSize) {
1212
maxSize = size
1313
maxConstraint = c

compiler/src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -717,21 +717,12 @@ object Contexts {
717717
def derived: GADTMap
718718
}
719719

720-
case class TvHandle(origin: TypeVarRef) extends Type with TypeVarHandle[TypeVarRef] {
721-
override def computeHash(bs: Hashable.Binders): Int = 0
722-
override def hash: Int = 0
723-
}
724-
725720
final class SmartGADTMap(
726-
private[this] var myConstraint: Constraint[TypeVarRef, TypeVarRefBinder] =
727-
new OrderingConstraint[TypeVarRef, TypeVarRefBinder](SimpleIdentityMap.Empty, SimpleIdentityMap.Empty, SimpleIdentityMap.Empty),
728-
private[this] var mapping: SimpleIdentityMap[Symbol, TvHandle] = SimpleIdentityMap.Empty,
729-
) extends GADTMap with ConstraintHandling[TypeVarRef, TypeVarRefBinder] {
721+
private[this] var myConstraint: Constraint = new OrderingConstraint(SimpleIdentityMap.Empty, SimpleIdentityMap.Empty, SimpleIdentityMap.Empty),
722+
private[this] var mapping: SimpleIdentityMap[Symbol, TypeVar] = SimpleIdentityMap.Empty,
723+
) extends GADTMap with ConstraintHandling {
730724
import dotty.tools.dotc.config.Printers.gadts
731725

732-
override def isVarRef(r: Type): Boolean = r.isInstanceOf[TypeParamRef] ||
733-
(r.isInstanceOf[TypeRef] && mapping.contains(r.typeSymbol(ctx)))
734-
735726
override def debugBoundsDescription(implicit ctx: Context): String = {
736727
val sb = new mutable.StringBuilder
737728
sb ++= constraint.show
@@ -751,18 +742,17 @@ object Contexts {
751742
try op finally myCtx = savedCtx
752743
}
753744

754-
override protected def constraint: OwnConstraint = myConstraint
755-
override protected def constraint_=(c: OwnConstraint) = myConstraint = c
745+
override protected def constraint = myConstraint
746+
override protected def constraint_=(c: Constraint) = myConstraint = c
756747

757748
override def isSubType(tp1: Type, tp2: Type): Boolean = ctx.typeComparer.isSubType(tp1, tp2)
758749
override def isSameType(tp1: Type, tp2: Type): Boolean = ctx.typeComparer.isSameType(tp1, tp2)
759750

760-
private[this] def tvar(sym: Symbol)(implicit ctx: Context): TvHandle = inCtx(ctx) {
751+
private[this] def tvar(sym: Symbol)(implicit ctx: Context): TypeVar = inCtx(ctx) {
761752
val res = mapping(sym) match {
762-
case tv: TvHandle => tv
753+
case tv: TypeVar => tv
763754
case null =>
764-
// val res = new TypeVar(sym.typeRef, creatorState = null)
765-
val res = TvHandle(sym.typeRef)
755+
val res = new TypeVar(sym.typeRef, creatorState = null)
766756
gadts.println(i"GADTMap: created tvar $sym -> $res")
767757
constraint = constraint.add(res.origin.binder, res :: Nil)
768758
mapping = mapping.updated(sym, res)
@@ -783,7 +773,7 @@ object Contexts {
783773
}
784774

785775
@annotation.tailrec def firstUninst(tp: Type): Type = tp match {
786-
case tv: TypeVarHandle[_] =>
776+
case tv: TypeVar =>
787777
val inst = _instType(tv.origin)
788778
if (inst.exists) firstUninst(inst) else tv
789779
case ref: TypeVarRef =>
@@ -815,15 +805,15 @@ object Contexts {
815805
}
816806

817807
val symRef: TypeVarRef = firstUninst(tvar(sym)) match {
818-
case tv: TypeVarHandle[_] => tv.origin
808+
case tv: TypeVar => tv.origin
819809
case inst =>
820810
gadts.println(i"instantiated: $sym -> $inst")
821811
return cautiousSubtype(inst, bound, isSubtype = isUpper, allowNarrowing = true)
822812
}
823813

824814
def doAddBound(bound: Type): Boolean = {
825815
val realBound = firstUninst(bound) match {
826-
case tv: TypeVarHandle[_] => tv.origin
816+
case tv: TypeVar => tv.origin
827817
case tp => tp
828818
}
829819

@@ -848,7 +838,7 @@ object Contexts {
848838

849839
val tvarBound = bound
850840
val res = tvarBound match {
851-
case boundTvar: TypeVarHandle[_] =>
841+
case boundTvar: TypeVar =>
852842
doAddBound(boundTvar)
853843
case tp => doAddBound(tp)
854844
}
@@ -874,6 +864,16 @@ object Contexts {
874864
this.myConstraint,
875865
this.mapping
876866
)
867+
868+
private final class TypeVarInsertingMap extends TypeMap {
869+
override def apply(tp: Type): Type = tp match {
870+
case tp: TypeRef =>
871+
val sym = tp.typeSymbol
872+
if (contains(sym)) tvar(sym) else tp
873+
case _ =>
874+
mapOver(tp)
875+
}
876+
}
877877
}
878878

879879
@sharable object EmptyGADTMap extends GADTMap {

0 commit comments

Comments
 (0)