Skip to content

Commit bcb46c2

Browse files
committed
Fix scala#2152: Instantiate dependent result type parameters
scala#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.
1 parent 77992c9 commit bcb46c2

File tree

4 files changed

+13
-8
lines changed

4 files changed

+13
-8
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ object NameKinds {
206206
val InlineAccessorName = new UniqueNameKind("$_inlineAccessor_$")
207207
val TempResultName = new UniqueNameKind("ev$")
208208
val EvidenceParamName = new UniqueNameKind("evidence$")
209-
val DepParamName = new UniqueNameKind("<param>")
209+
val DepParamName = new UniqueNameKind("(param)")
210210
val LazyImplicitName = new UniqueNameKind("$_lazy_implicit_$")
211211
val LazyLocalName = new UniqueNameKind("$lzy")
212212
val LazyLocalInitName = new UniqueNameKind("$lzyINIT")

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import SymDenotations._, Denotations.SingleDenotation
77
import config.Printers.typr
88
import util.Positions._
99
import NameOps._
10+
import NameKinds.DepParamName
1011
import Decorators._
1112
import StdNames._
1213
import Annotations._
@@ -169,6 +170,9 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
169170
simplify(l, theMap) & simplify(r, theMap)
170171
case OrType(l, r) =>
171172
simplify(l, theMap) | simplify(r, theMap)
173+
case tp: TypeVar if tp.origin.paramName.is(DepParamName) =>
174+
val effectiveVariance = if (theMap == null) 1 else theMap.variance
175+
tp.instanceOpt orElse tp.instantiate(fromBelow = effectiveVariance != -1)
172176
case _ =>
173177
(if (theMap != null) theMap else new SimplifyMap).mapOver(tp)
174178
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3508,7 +3508,7 @@ object Types {
35083508

35093509
def apply(tp: Type): Type
35103510

3511-
protected var variance = 1
3511+
protected[core] var variance = 1
35123512

35133513
protected def derivedSelect(tp: NamedType, pre: Type): Type =
35143514
tp.derivedSelect(pre)

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -377,9 +377,10 @@ object ProtoTypes {
377377
* Also, if `owningTree` is non-empty, add a type variable for each parameter.
378378
* @return The added type lambda, and the list of created type variables.
379379
*/
380-
def constrained(tl: TypeLambda, owningTree: untpd.Tree)(implicit ctx: Context): (TypeLambda, List[TypeTree]) = {
380+
def constrained(tl: TypeLambda, owningTree: untpd.Tree, alwaysAddTypeVars: Boolean = false)(implicit ctx: Context): (TypeLambda, List[TypeTree]) = {
381381
val state = ctx.typerState
382-
assert(!(ctx.typerState.isCommittable && owningTree.isEmpty),
382+
val addTypeVars = alwaysAddTypeVars || !owningTree.isEmpty
383+
assert(!(ctx.typerState.isCommittable && !addTypeVars),
383384
s"inconsistent: no typevars were added to committable constraint ${state.constraint}")
384385

385386
def newTypeVars(tl: TypeLambda): List[TypeTree] =
@@ -392,7 +393,7 @@ object ProtoTypes {
392393
val added =
393394
if (state.constraint contains tl) tl.newLikeThis(tl.paramNames, tl.paramInfos, tl.resultType)
394395
else tl
395-
val tvars = if (owningTree.isEmpty) Nil else newTypeVars(added)
396+
val tvars = if (addTypeVars) newTypeVars(added) else Nil
396397
ctx.typeComparer.addToConstraint(added, tvars.tpes.asInstanceOf[List[TypeVar]])
397398
(added, tvars)
398399
}
@@ -401,12 +402,12 @@ object ProtoTypes {
401402
def constrained(tl: TypeLambda)(implicit ctx: Context): TypeLambda = constrained(tl, EmptyTree)._1
402403

403404
/** Create a new TypeParamRef that represents a dependent method parameter singleton */
404-
def newDepTypeParamRef(tp: Type)(implicit ctx: Context): TypeParamRef = {
405+
def newDepTypeParamRef(tp: Type)(implicit ctx: Context): TypeVar = {
405406
val poly = PolyType(DepParamName.fresh().toTypeName :: Nil)(
406407
pt => TypeBounds.upper(AndType(tp, defn.SingletonType)) :: Nil,
407408
pt => defn.AnyType)
408-
ctx.typeComparer.addToConstraint(poly, Nil)
409-
TypeParamRef(poly, 0)
409+
constrained(poly, untpd.EmptyTree, alwaysAddTypeVars = true)
410+
._2.head.tpe.asInstanceOf[TypeVar]
410411
}
411412

412413
/** The result type of `mt`, where all references to parameters of `mt` are

0 commit comments

Comments
 (0)