Skip to content

Commit b914fb7

Browse files
committed
Cleanups prompted by reviews.
1 parent 3fa9819 commit b914fb7

File tree

7 files changed

+43
-46
lines changed

7 files changed

+43
-46
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ object Config {
3737
* on only for specific debugging as normally instantiation to Nothing
3838
* is not an error consdition.
3939
*/
40-
final val flagInstantiationToNothing = false
40+
final val failOnInstantiationToNothing = false
4141

4242
/** Enable noDoubleDef checking if option "-YnoDoubleDefs" is set.
4343
* The reason to have an option as well as the present global switch is

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

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,14 @@ import config.Printers._
99

1010
/** Methods for adding constraints and solving them.
1111
*
12-
* Constraints are required to be in normalized form. This means
13-
* (1) if P <: Q in C then also Q >: P in C
14-
* (2) if P r Q in C and Q r R in C then also P r R in C, where r is <: or :>
15-
*
16-
* "P <: Q in C" means here: There is a constraint P <: H[Q],
17-
* where H is the multi-hole context given by:
18-
*
19-
* H = []
20-
* H & T
21-
* T & H
22-
* H | H
23-
*
24-
* (the idea is that a parameter Q in a H context is guaranteed to be a supertype of P).
25-
*
26-
* "P >: Q in C" means: There is a constraint P >: L[Q],
27-
* where L is the multi-hole context given by:
28-
*
29-
* L = []
30-
* L | T
31-
* T | L
32-
* L & L
12+
* What goes into a Constraint as opposed to a ConstrainHandler?
13+
*
14+
* Constraint code is purely functional: Operations get constraints and produce new ones.
15+
* Constraint code does not have access to a type-comparer. Anything regarding lubs and glbs has to be done
16+
* elsewhere.
17+
*
18+
* By comparison: Constraint handlers are parts of type comparers and can use their functionality.
19+
* Constraint handlers update the current constraint as a side effect.
3320
*/
3421
trait ConstraintHandling {
3522

@@ -59,7 +46,7 @@ trait ConstraintHandling {
5946
def description = i"constraint $param <: $bound to\n$constraint"
6047
if (bound.isRef(defn.NothingClass) && ctx.typerState.isGlobalCommittable) {
6148
def msg = s"!!! instantiated to Nothing: $param, constraint = ${constraint.show}"
62-
if (Config.flagInstantiationToNothing) assert(false, msg)
49+
if (Config.failOnInstantiationToNothing) assert(false, msg)
6350
else ctx.log(msg)
6451
}
6552
constr.println(i"adding $description")
@@ -86,9 +73,6 @@ trait ConstraintHandling {
8673
def description = i"ordering $p1 <: $p2 to\n$constraint"
8774
val res =
8875
if (constraint.isLess(p2, p1)) unify(p2, p1)
89-
// !!! this is direction dependent - unify(p1, p2) makes i94-nada loop forever.
90-
// Need to investigate why this is the case.
91-
// The symptom is that we get a subtyping constraint of the form P { ... } <: P
9276
else {
9377
val down1 = p1 :: constraint.exclusiveLower(p1, p2)
9478
val up2 = p2 :: constraint.exclusiveUpper(p2, p1)
@@ -193,20 +177,24 @@ trait ConstraintHandling {
193177
case _ => param.binder.paramBounds(param.paramNum)
194178
}
195179

196-
/** If `p` is a parameter of `pt`, propagate the non-parameter bounds
197-
* of `p` to the parameters known to be less or greater than `p`.
180+
/** Add polytype `pt`, possibly with type variables `tvars`, to current constraint
181+
* and propagate all bounds.
182+
* @param tvars See Constraint#add
198183
*/
199-
def initialize(pt: PolyType): Boolean =
200-
checkPropagated(i"initialized $pt") {
201-
pt.paramNames.indices.forall { i =>
202-
val param = PolyParam(pt, i)
203-
val bounds = constraint.nonParamBounds(param)
204-
val lower = constraint.lower(param)
205-
val upper = constraint.upper(param)
206-
if (lower.nonEmpty && !bounds.lo.isRef(defn.NothingClass) ||
207-
upper.nonEmpty && !bounds.hi.isRef(defn.AnyClass)) println(i"INIT*** $pt")
208-
lower.forall(addOneBound(_, bounds.hi, isUpper = true)) &&
209-
upper.forall(addOneBound(_, bounds.lo, isUpper = false))
184+
def addToConstraint(pt: PolyType, tvars: List[TypeVar]): Unit =
185+
assert {
186+
checkPropagated(i"initialized $pt") {
187+
constraint = constraint.add(pt, tvars)
188+
pt.paramNames.indices.forall { i =>
189+
val param = PolyParam(pt, i)
190+
val bounds = constraint.nonParamBounds(param)
191+
val lower = constraint.lower(param)
192+
val upper = constraint.upper(param)
193+
if (lower.nonEmpty && !bounds.lo.isRef(defn.NothingClass) ||
194+
upper.nonEmpty && !bounds.hi.isRef(defn.AnyClass)) println(i"INIT*** $pt")
195+
lower.forall(addOneBound(_, bounds.hi, isUpper = true)) &&
196+
upper.forall(addOneBound(_, bounds.lo, isUpper = false))
197+
}
210198
}
211199
}
212200

@@ -238,6 +226,7 @@ trait ConstraintHandling {
238226
/** Check that constraint is fully propagated. See comment in Config.checkConstraintsPropagated */
239227
def checkPropagated(msg: => String)(result: Boolean): Boolean = {
240228
if (Config.checkConstraintsPropagated && result && addConstraintInvocations == 0) {
229+
val saved = frozenConstraint
241230
frozenConstraint = true
242231
for (p <- constraint.domainParams) {
243232
def check(cond: => Boolean, q: PolyParam, ordering: String, explanation: String): Unit =
@@ -249,7 +238,7 @@ trait ConstraintHandling {
249238
check(constraint.isLess(l, p), l, ">:", "reverse ordering (<:) missing")
250239
}
251240
}
252-
frozenConstraint = false
241+
frozenConstraint = saved
253242
}
254243
result
255244
}

src/dotty/tools/dotc/core/Symbols.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,8 @@ trait Symbols { this: Context =>
256256
tparams
257257
}
258258

259-
/** Create a new skolem symbol. This is not the same as SkolemType, even thouggh the
260-
* motivation (create a singleton referencing to a type)= is similar.
259+
/** Create a new skolem symbol. This is not the same as SkolemType, even though the
260+
* motivation (create a singleton referencing to a type) is similar.
261261
*/
262262
def newSkolem(tp: Type) = newSymbol(defn.RootClass, nme.SKOLEM, SyntheticArtifact | Permanent, tp)
263263

src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
247247
def flagNothingBound = {
248248
if (!frozenConstraint && tp2.isRef(defn.NothingClass) && state.isGlobalCommittable) {
249249
def msg = s"!!! instantiated to Nothing: $tp1, constraint = ${constraint.show}"
250-
if (Config.flagInstantiationToNothing) assert(false, msg)
250+
if (Config.failOnInstantiationToNothing) assert(false, msg)
251251
else ctx.log(msg)
252252
}
253253
true

src/dotty/tools/dotc/typer/Mode.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ object Mode {
3131
val ImplicitsEnabled = newMode(2, "ImplicitsEnabled")
3232
val InferringReturnType = newMode(3, "InferringReturnType")
3333

34+
/** This mode bit is set if we collect information without reference to a valid
35+
* context with typerstate and constraint. This is typically done when we
36+
* cache the eligibility of implicits. Caching needs to be done across different constraints.
37+
* Therefore, if TypevarsMissContext is set, subtyping becomes looser, and assumes
38+
* that PolyParams can be sub- and supertypes of anything. See TypeComparer.
39+
*/
3440
val TypevarsMissContext = newMode(4, "TypevarsMissContext")
3541
val CheckCyclic = newMode(5, "CheckCyclic")
3642

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,7 @@ object ProtoTypes {
324324
if (state.constraint contains pt) pt.duplicate(pt.paramNames, pt.paramBounds, pt.resultType)
325325
else pt
326326
val tvars = if (owningTree.isEmpty) Nil else newTypeVars(added)
327-
state.constraint = state.constraint.add(added, tvars)
328-
ctx.typeComparer.initialize(added)
327+
ctx.typeComparer.addToConstraint(added, tvars)
329328
(added, tvars)
330329
}
331330

tests/pending/pos/compound.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// There's still a problem with var's here, presumably because they are not paths.
2+
// Needs some more investigation.
13
abstract class A { type T }
24

35
abstract class B { val xz: Any }
@@ -7,7 +9,8 @@ abstract class Test {
79
var xx: A with B { type T; val xz: T } = null;
810
xx = yy;
911
}
12+
1013
abstract class Test2 {
11-
var yy: A with B { type T; val xz: T } = null;
14+
val yy: A with B { type T; val xz: T } = null;
1215
val xx: A with B { type T; val xz: T } = yy
1316
}

0 commit comments

Comments
 (0)