diff options
-rw-r--r-- | src/dotty/tools/dotc/core/Constraint.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TyperState.scala | 85 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 4 |
4 files changed, 32 insertions, 79 deletions
diff --git a/src/dotty/tools/dotc/core/Constraint.scala b/src/dotty/tools/dotc/core/Constraint.scala index 8ffdce71c..bee21d499 100644 --- a/src/dotty/tools/dotc/core/Constraint.scala +++ b/src/dotty/tools/dotc/core/Constraint.scala @@ -198,8 +198,16 @@ class Constraint(val myMap: SimpleMap[PolyType, Array[Type]]) extends AnyVal wit Text(assocs, "\n") } - override def toText(printer: Printer): Text = - "Constraint(" ~ constrainedTypesText(printer) ~ ") {" ~ constraintText(2, printer) ~ "}" + override def toText(printer: Printer): Text = { + val header: Text = "Constraint(" + val uninstVarsText = " uninstVars = " ~ + Text(uninstVars map (_.toText(printer)), ", ") ~ ";" + val constrainedText = + " constrained types = " ~ constrainedTypesText(printer) ~ ";" + val constraintsText = + " constraint = " ~ constraintText(3, printer) ~ ")" + Text.lines(List(header, uninstVarsText, constrainedText, constraintsText)) + } } object Constraint { diff --git a/src/dotty/tools/dotc/core/TyperState.scala b/src/dotty/tools/dotc/core/TyperState.scala index 8b5e2c85e..53782c642 100644 --- a/src/dotty/tools/dotc/core/TyperState.scala +++ b/src/dotty/tools/dotc/core/TyperState.scala @@ -10,17 +10,18 @@ import reporting._ import printing.{Showable, Printer} import printing.Texts._ import collection.mutable -import annotation.elidable class TyperState(val reporter: Reporter) extends DotClass with Showable { /** The current constraint set */ def constraint: Constraint = new Constraint(SimpleMap.Empty) + def constraint_=(c: Constraint): Unit = {} def uninstVars = constraint.uninstVars - /** A map that records for instantiated type vars their instance type. - * Used only in a temporary way for contexts that may be retracted + /** Gives for each instantiated type var that does not yet have its `inst` field + * set, the instance value stored in the constraint. Storing instances in constraints + * is done only in a temporary way for contexts that may be retracted * without also retracting the type var as a whole. */ def instType(tvar: TypeVar): Type = constraint.at(tvar.origin) match { @@ -28,20 +29,16 @@ class TyperState(val reporter: Reporter) extends DotClass with Showable { case tp => tp } - def constraint_=(c: Constraint): Unit = {} - + /** A fresh typer state with the same constraint as this one. + * @param isCommittable The constraint can be committed to an exclosing context. + */ def fresh(isCommittable: Boolean): TyperState = this + /** Commit state so that it gets propagated to enclosing context */ def commit()(implicit ctx: Context): Unit = unsupported("commit") - def isCommittable: Boolean = false - - @elidable(elidable.FINER) - def checkConsistent(implicit ctx: Context) = () - @elidable(elidable.FINER) - def enableChecking(b: Boolean): Boolean = true - - def withCheckingDisabled[T](op: => T)(implicit ctx: Context): T = op + /** Is it allowed to commit this state? */ + def isCommittable: Boolean = false override def toText(printer: Printer): Text = "ImmutableTyperState" } @@ -50,13 +47,9 @@ class MutableTyperState(previous: TyperState, reporter: Reporter, override val i extends TyperState(reporter) { private var myConstraint: Constraint = previous.constraint - private var checkingEnabled: Boolean = true override def constraint = myConstraint - override def constraint_=(c: Constraint) = { - myConstraint = c - checkConsistent() - } + override def constraint_=(c: Constraint) = myConstraint = c override def fresh(isCommittable: Boolean): TyperState = new MutableTyperState(this, new StoreReporter, isCommittable) @@ -68,11 +61,10 @@ extends TyperState(reporter) { * instantiated instead. */ override def commit()(implicit ctx: Context) = { - checkConsistent val targetState = ctx.typerState - val prev = targetState.enableChecking(false) + assert(isCommittable) + assert(targetState.isCommittable) targetState.constraint = constraint - targetState.enableChecking(prev) val toCollect = new mutable.ListBuffer[PolyType] constraint foreachTypeVar { tvar => @@ -90,59 +82,10 @@ extends TyperState(reporter) { for (poly <- toCollect) targetState.constraint = targetState.constraint.remove(poly) - targetState.checkConsistent // !!! DEBUG - reporter.flush() } - @elidable(elidable.FINER) - def checkConsistent(show: Showable => String = MutableTyperState.toStr): Unit = if (checkingEnabled) { - def err(msg: String, what: Showable) = s"$msg: ${show(what)}\n${show(this)}" - for (tvar <- uninstVars) - assert(constraint contains tvar.origin, err("unconstrained type var", tvar.origin)) - if (isCommittable) { - val undetParams = uninstVars map (_.origin) - for (param <- constraint.domainParams) - assert(undetParams contains param, err("junk constraint on", param)) - } - } - - @elidable(elidable.FINER) - override def checkConsistent(implicit ctx: Context): Unit = checkConsistent(_.show) - - @elidable(elidable.FINER) - override def enableChecking(b: Boolean) = { - val prev = checkingEnabled - checkingEnabled = b - prev - } - - override def withCheckingDisabled[T](op: => T)(implicit ctx: Context): T = { - val prev = enableChecking(false) - var thrown = false - try op - catch { - case ex: Throwable => - thrown = true - throw ex - } - finally { - enableChecking(prev) - if (!thrown) checkConsistent - } - } - - override def toText(printer: Printer): Text = { - val header: Text = "Typer state:" - val uninstVarsText = - " uninstVars: " ~ - Text(uninstVars map (_.toText(printer)), ", ") ~ "." - val constrainedText = - " constrained types: " ~ constraint.constrainedTypesText(printer) ~ "." - val constraintText = - " constraint: " ~ constraint.constraintText(3, printer) - Text.lines(List(header, uninstVarsText, constrainedText, constraintText)) - } + override def toText(printer: Printer): Text = constraint.toText(printer) } object MutableTyperState { diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index f530ff986..8796b19ad 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -2032,12 +2032,10 @@ object Types { case OrType(tp1, tp2) => isSingleton(tp1) & isSingleton(tp2) case _ => false } - ctx.typerState.withCheckingDisabled { - var inst = ctx.typeComparer.approximation(origin, fromBelow) - if (fromBelow && isSingleton(inst) && !isSingleton(upperBound)) - inst = inst.widen - instantiateWith(inst.simplified) - } + var inst = ctx.typeComparer.approximation(origin, fromBelow) + if (fromBelow && isSingleton(inst) && !isSingleton(upperBound)) + inst = inst.widen + instantiateWith(inst.simplified) } /** Unwrap to instance (if instantiated) or origin (if not), until result diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index 8b3c19b71..599dc5f4e 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -208,6 +208,10 @@ object Inferencing { * @return The tracked polytype, and the list of created type variables. */ def track(pt: PolyType, owningTree: untpd.Tree): (PolyType, List[TypeVar]) = { + def howmany = if (owningTree.isEmpty) "no" else "some" + def committable = if (ctx.typerState.isCommittable) "committable" else "uncommittable" + assert(owningTree.isEmpty != ctx.typerState.isCommittable, + s"inconsistent: $howmany typevars were added to $committable constraint ${state.constraint}") val tracked = if (state.constraint contains pt) pt.copy(pt.paramNames, pt.paramBounds, pt.resultType) else pt |