Skip to content

Commit 4c91988

Browse files
committed
Add optional check that type variables in constraints are consistent
I verified that with the previous commit all compilation tests except two neg tests pass this check.
1 parent 73abb32 commit 4c91988

File tree

5 files changed

+27
-7
lines changed

5 files changed

+27
-7
lines changed

compiler/src/dotty/tools/dotc/config/Config.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ object Config {
3434
*/
3535
inline val checkConstraintsPropagated = false
3636

37+
/** If a constraint is over a type lambda `tl` and `tvar` is one of
38+
* the type variables associated with `tl` in the constraint, check
39+
* that the origin of `tvar` is a parameter of `tl`.
40+
*/
41+
inline val checkConsistentVars = false
42+
3743
/** Check that constraints of globally committable typer states are closed.
3844
* NOTE: When enabled, the check can cause CyclicReference errors because
3945
* it traverses all elements of a type. Such failures were observed when

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ abstract class Constraint extends Showable {
174174
/** Check that constraint only refers to TypeParamRefs bound by itself */
175175
def checkClosed()(using Context): Unit
176176

177+
/** Check that every typevar om this constraint has as origin a type parameter
178+
* of athe type lambda that is associated with the typevar itself.
179+
*/
180+
def checkConsistentVars()(using Context): Unit
181+
177182
/** A string describing the constraint's contents without a header or trailer */
178183
def contentsToString(using Context): String
179184
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,13 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
523523
}
524524
else tl
525525

526+
def checkConsistentVars()(using Context): Unit =
527+
for param <- domainParams do
528+
typeVarOfParam(param) match
529+
case tvar: TypeVar =>
530+
assert(tvar.origin == param, i"mismatch $tvar, $param")
531+
case _ =>
532+
526533
// ---------- Exploration --------------------------------------------------------
527534

528535
def domainLambdas: List[TypeLambda] = boundsMap.keys

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ class TyperState() {
4444
def constraint_=(c: Constraint)(using Context): Unit = {
4545
if (Config.debugCheckConstraintsClosed && isGlobalCommittable) c.checkClosed()
4646
myConstraint = c
47+
if Config.checkConsistentVars && !ctx.reporter.errorsReported then
48+
c.checkConsistentVars()
4749
}
4850

4951
private var previousConstraint: Constraint = _
@@ -177,11 +179,11 @@ class TyperState() {
177179
if !tvar.inst.exists then
178180
val inst = constraint.instType(tvar)
179181
if inst.exists then
180-
tvar.inst = inst
181-
val lam = tvar.origin.binder
182-
if constraint.isRemovable(lam) then toCollect += lam
183-
for poly <- toCollect do
184-
constraint = constraint.remove(poly)
182+
tvar.setInst(inst)
183+
val tl = tvar.origin.binder
184+
if constraint.isRemovable(tl) then toCollect += tl
185+
for tl <- toCollect do
186+
constraint = constraint.remove(tl)
185187

186188
override def toString: String = {
187189
def ids(state: TyperState): List[String] =

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4396,7 +4396,7 @@ object Types {
43964396
private var myInst: Type = NoType
43974397

43984398
private[core] def inst: Type = myInst
4399-
private[core] def inst_=(tp: Type): Unit =
4399+
private[core] def setInst(tp: Type): Unit =
44004400
myInst = tp
44014401
if tp.exists && owningState != null then
44024402
val owningState1 = owningState.get
@@ -4454,7 +4454,7 @@ object Types {
44544454
assert(tp ne this, s"self instantiation of ${tp.show}, constraint = ${ctx.typerState.constraint.show}")
44554455
typr.println(s"instantiating ${this.show} with ${tp.show}")
44564456
if ((ctx.typerState eq owningState.get) && !TypeComparer.subtypeCheckInProgress)
4457-
inst = tp
4457+
setInst(tp)
44584458
ctx.typerState.constraint = ctx.typerState.constraint.replace(origin, tp)
44594459
tp
44604460
}

0 commit comments

Comments
 (0)