diff options
author | Martin Odersky <odersky@gmail.com> | 2013-11-21 23:44:32 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-11-21 23:44:32 +0100 |
commit | e38813ac1362a1d528dfa1ee79f0f8b0d6f7ccb8 (patch) | |
tree | d8c2e1a9b2c1b86373f1ae125af617578ab8696f /src/dotty/tools/dotc/typer | |
parent | ed6d9327c5efc70db59d5fd90612e4a5a58cff8c (diff) | |
download | dotty-e38813ac1362a1d528dfa1ee79f0f8b0d6f7ccb8.tar.gz dotty-e38813ac1362a1d528dfa1ee79f0f8b0d6f7ccb8.tar.bz2 dotty-e38813ac1362a1d528dfa1ee79f0f8b0d6f7ccb8.zip |
Consolidation of TyperState and Constraint
Removing undetVars and instTypes as separately assignable fields. This is better for maintaining invariants by design.
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 46 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 5 |
2 files changed, 26 insertions, 25 deletions
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index ebbd6cd41..8b3c19b71 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -204,15 +204,31 @@ object Inferencing { * If the constraint contains already some of these parameters in its domain, * make a copy of the polytype and add the copy's type parameters instead. * Return either the original polytype, or the copy, if one was made. + * Also, if `owningTree` is non-empty, add a type variable for each parameter. + * @return The tracked polytype, and the list of created type variables. */ - def track(pt: PolyType): PolyType = { + def track(pt: PolyType, owningTree: untpd.Tree): (PolyType, List[TypeVar]) = { val tracked = if (state.constraint contains pt) pt.copy(pt.paramNames, pt.paramBounds, pt.resultType) else pt - state.constraint = state.constraint + tracked - tracked + val tvars = if (owningTree.isEmpty) Nil else newTypeVars(tracked, owningTree) + state.constraint = state.constraint.add(tracked, tvars) + //if (!owningTree.isEmpty) + // state.constraint = state.constraint.transformed(pt, _.substParams(pt, tvars)) + (tracked, tvars) } + /** Create new type variables for the parameters of a poly type. + * @param pos The position of the new type variables (relevant for + * interpolateUndetVars + */ + private def newTypeVars(pt: PolyType, owningTree: untpd.Tree): List[TypeVar] = + for (n <- (0 until pt.paramNames.length).toList) + yield new TypeVar(PolyParam(pt, n), ctx.typerState, owningTree) + + /** Same as `track(pt, EmptyTree)`, but returns just the created polytype */ + def track(pt: PolyType): PolyType = track(pt, EmptyTree)._1 + /** Interpolate those undetermined type variables in the widened type of this tree * which are introduced by type application contained in the tree. * If such a variable appears covariantly in type `tp` or does not appear at all, @@ -222,14 +238,14 @@ object Inferencing { def interpolateUndetVars(tree: Tree): Unit = Stats.track("interpolateUndetVars") { val tp = tree.tpe.widen - println(s"interpolate undet vars in ${tp.show}, pos = ${tree.pos}, mode = ${ctx.mode}, undets = ${ctx.typerState.undetVars map (tvar => s"${tvar.show}@${tvar.owningTree.pos}")}") - println(s"qualifying undet vars: ${ctx.typerState.undetVars filter qualifies map (_.show)}") + println(s"interpolate undet vars in ${tp.show}, pos = ${tree.pos}, mode = ${ctx.mode}, undets = ${ctx.typerState.uninstVars map (tvar => s"${tvar.show}@${tvar.owningTree.pos}")}") + println(s"qualifying undet vars: ${ctx.typerState.uninstVars filter qualifies map (_.show)}") println(s"fulltype: $tp") // !!! DEBUG println(s"constraint: ${ctx.typerState.constraint.show}") def qualifies(tvar: TypeVar) = tree contains tvar.owningTree val vs = tp.variances(tvar => - (ctx.typerState.undetVars contains tvar) && qualifies(tvar)) + (ctx.typerState.constraint contains tvar) && qualifies(tvar)) println(s"variances = $vs") var changed = false for ((tvar, v) <- vs) @@ -241,11 +257,12 @@ object Inferencing { if (changed) interpolateUndetVars(tree) else - for (tvar <- ctx.typerState.undetVars) + ctx.typerState.constraint.foreachUninstVar { tvar => if (!(vs contains tvar) && qualifies(tvar)) { println(s"instantiating non-occurring $tvar in $tp") tvar.instantiate(fromBelow = true) } + } } /** Instantiate undetermined type variables to that type `tp` is @@ -253,7 +270,7 @@ object Inferencing { * typevar is not uniquely determined, return that typevar in a Some. */ def maximizeType(tp: Type): Option[TypeVar] = Stats.track("maximizeType") { - val vs = tp.variances(tvar => ctx.typerState.undetVars contains tvar) + val vs = tp.variances(tvar => ctx.typerState.constraint contains tvar) var result: Option[TypeVar] = None for ((tvar, v) <- vs) if (v == 1) tvar.instantiate(fromBelow = false) @@ -266,19 +283,6 @@ object Inferencing { result } - /** Create new type variables for the parameters of a poly type. - * @param pos The position of the new type variables (relevant for - * interpolateUndetVars - */ - def newTypeVars(pt: PolyType, owningTree: untpd.Tree): List[TypeVar] = { - val state = ctx.typerState - val tvars = - for (n <- (0 until pt.paramNames.length).toList) - yield new TypeVar(PolyParam(pt, n), state, owningTree) - state.constraint = state.constraint.transformed(pt, _.substParams(pt, tvars)) - tvars - } - def isSubTypes(actuals: List[Type], formals: List[Type])(implicit ctx: Context): Boolean = formals match { case formal :: formals1 => actuals match { diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 9780e8d2e..4242b5c99 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -1100,10 +1100,7 @@ class Typer extends Namer with Applications with Implicits { case poly: PolyType => if (pt.isInstanceOf[PolyProto]) tree else { - val tvars = ctx.typerState.withCheckingDisabled { - val tracked = ctx.track(poly) - ctx.newTypeVars(tracked, tree) - } + val (_, tvars) = ctx.track(poly, tree) adaptInterpolated(tree appliedToTypes tvars, pt) } case wtp => |