From 053cd236ee12f877cfd71affb9a62a417f917d3d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 10 Apr 2017 16:35:01 +0200 Subject: Fix #2152: Instantiate dependent result type parameters #2152 shows that dependent result type parameters can end up in the types of terms, so we have to eliminate them. If we don't we get orphan parameters in pickling. Fix method name and comment --- compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala') diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 398a7a17e..5d8240362 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -377,9 +377,10 @@ object ProtoTypes { * Also, if `owningTree` is non-empty, add a type variable for each parameter. * @return The added type lambda, and the list of created type variables. */ - def constrained(tl: TypeLambda, owningTree: untpd.Tree)(implicit ctx: Context): (TypeLambda, List[TypeTree]) = { + def constrained(tl: TypeLambda, owningTree: untpd.Tree, alwaysAddTypeVars: Boolean = false)(implicit ctx: Context): (TypeLambda, List[TypeTree]) = { val state = ctx.typerState - assert(!(ctx.typerState.isCommittable && owningTree.isEmpty), + val addTypeVars = alwaysAddTypeVars || !owningTree.isEmpty + assert(!(ctx.typerState.isCommittable && !addTypeVars), s"inconsistent: no typevars were added to committable constraint ${state.constraint}") def newTypeVars(tl: TypeLambda): List[TypeTree] = @@ -392,7 +393,7 @@ object ProtoTypes { val added = if (state.constraint contains tl) tl.newLikeThis(tl.paramNames, tl.paramInfos, tl.resultType) else tl - val tvars = if (owningTree.isEmpty) Nil else newTypeVars(added) + val tvars = if (addTypeVars) newTypeVars(added) else Nil ctx.typeComparer.addToConstraint(added, tvars.tpes.asInstanceOf[List[TypeVar]]) (added, tvars) } @@ -400,13 +401,13 @@ object ProtoTypes { /** Same as `constrained(tl, EmptyTree)`, but returns just the created type lambda */ def constrained(tl: TypeLambda)(implicit ctx: Context): TypeLambda = constrained(tl, EmptyTree)._1 - /** Create a new TypeParamRef that represents a dependent method parameter singleton */ - def newDepTypeParamRef(tp: Type)(implicit ctx: Context): TypeParamRef = { + /** Create a new TypeVar that represents a dependent method parameter singleton */ + def newDepTypeVar(tp: Type)(implicit ctx: Context): TypeVar = { val poly = PolyType(DepParamName.fresh().toTypeName :: Nil)( pt => TypeBounds.upper(AndType(tp, defn.SingletonType)) :: Nil, pt => defn.AnyType) - ctx.typeComparer.addToConstraint(poly, Nil) - TypeParamRef(poly, 0) + constrained(poly, untpd.EmptyTree, alwaysAddTypeVars = true) + ._2.head.tpe.asInstanceOf[TypeVar] } /** The result type of `mt`, where all references to parameters of `mt` are @@ -415,7 +416,7 @@ object ProtoTypes { def resultTypeApprox(mt: MethodType)(implicit ctx: Context): Type = if (mt.isDependent) { def replacement(tp: Type) = - if (ctx.mode.is(Mode.TypevarsMissContext)) WildcardType else newDepTypeParamRef(tp) + if (ctx.mode.is(Mode.TypevarsMissContext)) WildcardType else newDepTypeVar(tp) mt.resultType.substParams(mt, mt.paramInfos.map(replacement)) } else mt.resultType -- cgit v1.2.3