Skip to content

Commit d03e626

Browse files
committed
Change Config flags
Introduce separate Config flags that enable level checking on constraints or level checking on instantiation.
1 parent bae9509 commit d03e626

File tree

4 files changed

+18
-12
lines changed

4 files changed

+18
-12
lines changed

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

+7-4
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,12 @@ object Config {
227227
*/
228228
inline val reuseSymDenotations = true
229229

230-
/** If true, check levels of type variables and create fresh ones as needed.
231-
* This is necessary for soundness (see 3ab18a9), but also causes several
232-
* regressions that should be fixed before turning this on.
230+
/** If `checkLevelsOnConstraints` is true, check levels of type variables
231+
* and create fresh ones as needed when bounds are first entered intot he constraint.
232+
* If `checkLevelsOnInstantiation` is true, allow level-incorrect constraints but
233+
* fix levels on type variable instantiation.
233234
*/
234-
inline val checkLevels = false
235+
inline val checkLevelsOnConstraints = false
236+
inline val checkLevelsOnInstantiation = true
237+
235238
}

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

+9-6
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,15 @@ trait ConstraintHandling {
103103
* of `1`. So the lower bound is `1 | x.M` and when we level-avoid that we
104104
* get `1 | Int & String`, which simplifies to `Int`.
105105
*/
106-
protected var trustBounds = true
106+
private var myTrustBounds = true
107107

108108
inline def withUntrustedBounds(op: => Type): Type =
109-
val saved = trustBounds
110-
trustBounds = false
111-
try op finally trustBounds = saved
109+
val saved = myTrustBounds
110+
myTrustBounds = false
111+
try op finally myTrustBounds = saved
112+
113+
def trustBounds: Boolean =
114+
!Config.checkLevelsOnInstantiation || myTrustBounds
112115

113116
def checkReset() =
114117
assert(addConstraintInvocations == 0)
@@ -131,7 +134,7 @@ trait ConstraintHandling {
131134
level <= maxLevel
132135
|| ctx.isAfterTyper || !ctx.typerState.isCommittable // Leaks in these cases shouldn't break soundness
133136
|| level == Int.MaxValue // See `nestingLevel` above.
134-
|| !Config.checkLevels
137+
|| !Config.checkLevelsOnConstraints
135138

136139
/** If `param` is nested deeper than `maxLevel`, try to instantiate it to a
137140
* fresh type variable of level `maxLevel` and return the new variable.
@@ -518,7 +521,7 @@ trait ConstraintHandling {
518521
if !fromBelow then variance = -1
519522
def toAvoid(tp: NamedType) = needsFix(tp)
520523

521-
if ctx.isAfterTyper then tp
524+
if !Config.checkLevelsOnInstantiation || ctx.isAfterTyper then tp
522525
else
523526
val needsLeveling = NeedsLeveling()
524527
if needsLeveling(false, tp) then

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ class TreePickler(pickler: TastyPickler) {
206206
}
207207
else if (tpe.prefix == NoPrefix) {
208208
writeByte(if (tpe.isType) TYPEREFdirect else TERMREFdirect)
209-
if Config.checkLevels && !symRefs.contains(sym) && !sym.isPatternBound && !sym.hasAnnotation(defn.QuotedRuntimePatterns_patternTypeAnnot) then
209+
if Config.checkLevelsOnConstraints && !symRefs.contains(sym) && !sym.isPatternBound && !sym.hasAnnotation(defn.QuotedRuntimePatterns_patternTypeAnnot) then
210210
report.error(i"pickling reference to as yet undefined $tpe with symbol ${sym}", sym.srcPos)
211211
pickleSymRef(sym)
212212
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1687,7 +1687,7 @@ class Namer { typer: Typer =>
16871687
// Examples that fail otherwise are pos/scalaz-redux.scala and pos/java-futures.scala.
16881688
// So fixing levels at instantiation avoids the soundness problem but apparently leads
16891689
// to type inference problems since it comes too late.
1690-
if !Config.checkLevels then
1690+
if !Config.checkLevelsOnConstraints then
16911691
val hygienicType = TypeOps.avoid(rhsType, termParamss.flatten)
16921692
if (!hygienicType.isValueType || !(hygienicType <:< tpt.tpe))
16931693
report.error(i"return type ${tpt.tpe} of lambda cannot be made hygienic;\n" +

0 commit comments

Comments
 (0)