aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-12-01 18:46:36 +0100
committerMartin Odersky <odersky@gmail.com>2016-12-01 18:46:36 +0100
commit5491e59569b85949ffb9d6e825c9e337adccdf2d (patch)
tree53748004acc490249de0f1dfa0b093292d842d7c /compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
parent47d208448e614125446c7f294f8231c3fb7108d6 (diff)
downloaddotty-5491e59569b85949ffb9d6e825c9e337adccdf2d.tar.gz
dotty-5491e59569b85949ffb9d6e825c9e337adccdf2d.tar.bz2
dotty-5491e59569b85949ffb9d6e825c9e337adccdf2d.zip
Fix #1757: Be more careful about positions of type variable binders
We interpolate a type variable if the current tree contains the type variables binding tree. Previously, this was the application owning the variable. However, sometimes this tree is transformed so that the containment test fails, and type variables are instantiated too late (in the case of #1757 this was never). We fix this by - setting the binding tree to the type tree that first contains the type variable - making sure that tree is never copied literally anywhere else. It's a tricky dance, but I believe we got it right now.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala11
1 files changed, 7 insertions, 4 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
index 9a20a452e..ed6b95c3b 100644
--- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
@@ -353,20 +353,23 @@ object ProtoTypes {
* Also, if `owningTree` is non-empty, add a type variable for each parameter.
* @return The added polytype, and the list of created type variables.
*/
- def constrained(pt: PolyType, owningTree: untpd.Tree)(implicit ctx: Context): (PolyType, List[TypeVar]) = {
+ def constrained(pt: PolyType, owningTree: untpd.Tree)(implicit ctx: Context): (PolyType, List[TypeTree]) = {
val state = ctx.typerState
assert(!(ctx.typerState.isCommittable && owningTree.isEmpty),
s"inconsistent: no typevars were added to committable constraint ${state.constraint}")
- def newTypeVars(pt: PolyType): List[TypeVar] =
+ def newTypeVars(pt: PolyType): List[TypeTree] =
for (n <- (0 until pt.paramNames.length).toList)
- yield new TypeVar(PolyParam(pt, n), state, owningTree, ctx.owner)
+ yield {
+ val tt = new TypeTree().withPos(owningTree.pos)
+ tt.withType(new TypeVar(PolyParam(pt, n), state, tt, ctx.owner))
+ }
val added =
if (state.constraint contains pt) pt.newLikeThis(pt.paramNames, pt.paramBounds, pt.resultType)
else pt
val tvars = if (owningTree.isEmpty) Nil else newTypeVars(added)
- ctx.typeComparer.addToConstraint(added, tvars)
+ ctx.typeComparer.addToConstraint(added, tvars.tpes.asInstanceOf[List[TypeVar]])
(added, tvars)
}