Skip to content

Commit

Permalink
Drop old TyperState based scheme and drop constrainRHSVars
Browse files Browse the repository at this point in the history
It seems constrainRHSVars is no longer needed with the new way to keep track
of hard type variables.
  • Loading branch information
odersky committed Aug 30, 2022
1 parent d15558d commit d7521bf
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 39 deletions.
18 changes: 3 additions & 15 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -485,20 +485,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
false
}

// If LHS is a hard union, constrain any type variables of the RHS with it as lower bound
// before splitting the LHS into its constituents. That way, the RHS variables are
// constrained by the hard union and can be instantiated to it. If we just split and add
// the two parts of the LHS separately to the constraint, the lower bound would become
// a soft union.
def constrainRHSVars(tp2: Type): Boolean = tp2.dealiasKeepRefiningAnnots match
case tp2: TypeParamRef if constraint contains tp2 => compareTypeParamRef(tp2)
case AndType(tp21, tp22) => constrainRHSVars(tp21) && constrainRHSVars(tp22)
case _ => true

/** Mark toplevel type vars in `tp2` as hard in the current constraint */
def hardenTypeVars(tp2: Type): Unit = tp2.dealiasKeepRefiningAnnots match
case tvar: TypeVar if constraint.contains(tvar.origin) =>
state.hardenTypeVar(tvar)
constraint = constraint.withHard(tvar)
case tp2: TypeParamRef if constraint.contains(tp2) =>
hardenTypeVars(constraint.typeVarOfParam(tp2))
Expand All @@ -507,9 +496,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
hardenTypeVars(tp2.tp2)
case _ =>

val res = widenOK
|| joinOK
|| (tp1.isSoft || constrainRHSVars(tp2)) && recur(tp11, tp2) && recur(tp12, tp2)
val res = widenOK || joinOK
|| recur(tp11, tp2) && recur(tp12, tp2)
|| containsAnd(tp1)
&& !joined
&& {
Expand All @@ -525,7 +513,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
// recursively, so we do it only once. See i14870.scala as a test case, which would
// loop for a very long time without the recursion brake.

if res && !tp1.isSoft && state.isCommittable then
if res && !tp1.isSoft && state.isCommittable then
// We use a heuristic here where every toplevel type variable on the right hand side
// is marked so that it converts all soft unions in its lower bound to hard unions
// before it is instantiated. The reason is that the variable's instance type will
Expand Down
27 changes: 6 additions & 21 deletions compiler/src/dotty/tools/dotc/core/TyperState.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,19 @@ object TyperState {

type LevelMap = SimpleIdentityMap[TypeVar, Integer]

opaque type Snapshot = (Constraint, TypeVars, TypeVars, LevelMap)
opaque type Snapshot = (Constraint, TypeVars, LevelMap)

extension (ts: TyperState)
def snapshot()(using Context): Snapshot =
(ts.constraint, ts.ownedVars, ts.hardVars, ts.upLevels)
(ts.constraint, ts.ownedVars, ts.upLevels)

def resetTo(state: Snapshot)(using Context): Unit =
val (constraint, ownedVars, hardVars, upLevels) = state
val (constraint, ownedVars, upLevels) = state
for tv <- ownedVars do
if !ts.ownedVars.contains(tv) then // tv has been instantiated
tv.resetInst(ts)
ts.constraint = constraint
ts.ownedVars = ownedVars
ts.hardVars = hardVars
ts.upLevels = upLevels
}

Expand Down Expand Up @@ -92,12 +91,6 @@ class TyperState() {
def ownedVars: TypeVars = myOwnedVars
def ownedVars_=(vs: TypeVars): Unit = myOwnedVars = vs

/** The set of type variables `tv` such that, if `tv` is instantiated to
* its lower bound, top-level soft unions in the instance type are converted
* to hard unions instead of being widened in `widenOr`.
*/
private var hardVars: TypeVars = _

private var upLevels: LevelMap = _

/** Initializes all fields except reporter, isCommittable, which need to be
Expand All @@ -110,7 +103,6 @@ class TyperState() {
this.myConstraint = constraint
this.previousConstraint = constraint
this.myOwnedVars = SimpleIdentitySet.empty
this.hardVars = SimpleIdentitySet.empty
this.upLevels = SimpleIdentityMap.empty
this.isCommitted = false
this
Expand All @@ -122,19 +114,12 @@ class TyperState() {
val ts = TyperState().init(this, this.constraint)
.setReporter(reporter)
.setCommittable(committable)
ts.hardVars = this.hardVars
ts.upLevels = upLevels
ts

/** The uninstantiated variables */
def uninstVars: collection.Seq[TypeVar] = constraint.uninstVars

/** Register type variable `tv` as hard. */
def hardenTypeVar(tv: TypeVar): Unit = hardVars += tv

/** Is type variable `tv` registered as hard? */
def isHard(tv: TypeVar): Boolean = hardVars.contains(tv)

/** The nestingLevel of `tv` in this typer state */
def nestingLevel(tv: TypeVar): Int =
val own = upLevels(tv)
Expand Down Expand Up @@ -195,11 +180,9 @@ class TyperState() {
constr.println(i"committing $this to $targetState, fromConstr = $constraint, toConstr = ${targetState.constraint}")
if targetState.constraint eq previousConstraint then
targetState.constraint = constraint
targetState.hardVars = hardVars
if !ownedVars.isEmpty then ownedVars.foreach(targetState.includeVar)
else
targetState.mergeConstraintWith(this)
for tv <- hardVars do targetState.hardVars += tv

upLevels.foreachBinding { (tv, level) =>
if level < targetState.nestingLevel(tv) then
Expand Down Expand Up @@ -247,7 +230,9 @@ class TyperState() {
val tvars = tl.paramRefs.map(other.typeVarOfParam(_)).collect { case tv: TypeVar => tv }
if this.isCommittable then
tvars.foreach(tvar =>
if !tvar.inst.exists && !isOwnedAnywhere(this, tvar) then includeVar(tvar))
if !tvar.inst.exists then
if !isOwnedAnywhere(this, tvar) then includeVar(tvar)
if constraint.isHard(tvar) then constraint = constraint.withHard(tvar))
typeComparer.addToConstraint(tl, tvars)
}) &&
// Integrate the additional constraints on type variables from `other`
Expand Down
4 changes: 1 addition & 3 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4721,9 +4721,7 @@ object Types {
instantiateWith(tp)

/** Widen unions when instantiating this variable in the current context? */
def widenUnions(using Context): Boolean =
if true then !ctx.typerState.constraint.isHard(this)
else !ctx.typerState.isHard(this)
def widenUnions(using Context): Boolean = !ctx.typerState.constraint.isHard(this)

/** For uninstantiated type variables: the entry in the constraint (either bounds or
* provisional instance value)
Expand Down

0 comments on commit d7521bf

Please sign in to comment.