Skip to content

Commit 4bb5baf

Browse files
committed
Further refactorings
- Use TypeLambda instead of PolyType. - Further harmonize factory operations
1 parent d97c584 commit 4bb5baf

21 files changed

+150
-146
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import config.Printers.constr
1414
* over values of the following types:
1515
*
1616
* - TypeLambda A constraint constrains the type parameters of a set of TypeLambdas
17-
* - TypeParamRef The parameters of the constrained polytypes
17+
* - TypeParamRef The parameters of the constrained type lambdas
1818
* - TypeVar Every constrained parameter might be associated with a TypeVar
1919
* that has the TypeParamRef as origin.
2020
*/
@@ -120,10 +120,10 @@ abstract class Constraint extends Showable {
120120
/** A new constraint with all entries coming from `pt` removed. */
121121
def remove(pt: TypeLambda)(implicit ctx: Context): This
122122

123-
/** The polytypes constrained by this constraint */
124-
def domainPolys: List[TypeLambda]
123+
/** The type lambdas constrained by this constraint */
124+
def domainLambdas: List[TypeLambda]
125125

126-
/** The polytype parameters constrained by this constraint */
126+
/** The type lambda parameters constrained by this constraint */
127127
def domainParams: List[TypeParamRef]
128128

129129
/** Check whether predicate holds for all parameters in constraint */

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ trait ConstraintHandling {
5151
*/
5252
protected var homogenizeArgs = false
5353

54-
/** We are currently comparing polytypes. Used as a flag for
54+
/** We are currently comparing type lambdas. Used as a flag for
5555
* optimization: when `false`, no need to do an expensive `pruneLambdaParams`
5656
*/
57-
protected var comparedPolyTypes: Set[PolyType] = Set.empty
57+
protected var comparedTypeLambdas: Set[TypeLambda] = Set.empty
5858

5959
private def addOneBound(param: TypeParamRef, bound: Type, isUpper: Boolean): Boolean =
6060
!constraint.contains(param) || {
@@ -307,21 +307,21 @@ trait ConstraintHandling {
307307
if (e.exists) e.bounds else param.binder.paramInfos(param.paramNum)
308308
}
309309

310-
/** Add polytype `pt`, possibly with type variables `tvars`, to current constraint
310+
/** Add type lambda `tl`, possibly with type variables `tvars`, to current constraint
311311
* and propagate all bounds.
312312
* @param tvars See Constraint#add
313313
*/
314-
def addToConstraint(pt: PolyType, tvars: List[TypeVar]): Unit =
314+
def addToConstraint(tl: TypeLambda, tvars: List[TypeVar]): Unit =
315315
assert {
316-
checkPropagated(i"initialized $pt") {
317-
constraint = constraint.add(pt, tvars)
318-
pt.paramNames.indices.forall { i =>
319-
val param = TypeParamRef(pt, i)
316+
checkPropagated(i"initialized $tl") {
317+
constraint = constraint.add(tl, tvars)
318+
tl.paramNames.indices.forall { i =>
319+
val param = TypeParamRef(tl, i)
320320
val bounds = constraint.nonParamBounds(param)
321321
val lower = constraint.lower(param)
322322
val upper = constraint.upper(param)
323323
if (lower.nonEmpty && !bounds.lo.isRef(defn.NothingClass) ||
324-
upper.nonEmpty && !bounds.hi.isRef(defn.AnyClass)) constr.println(i"INIT*** $pt")
324+
upper.nonEmpty && !bounds.hi.isRef(defn.AnyClass)) constr.println(i"INIT*** $tl")
325325
lower.forall(addOneBound(_, bounds.hi, isUpper = true)) &&
326326
upper.forall(addOneBound(_, bounds.lo, isUpper = false))
327327
}
@@ -358,10 +358,10 @@ trait ConstraintHandling {
358358
* missing.
359359
*/
360360
def pruneLambdaParams(tp: Type) =
361-
if (comparedPolyTypes.nonEmpty) {
361+
if (comparedTypeLambdas.nonEmpty) {
362362
val approx = new ApproximatingTypeMap {
363363
def apply(t: Type): Type = t match {
364-
case t @ TypeParamRef(pt: PolyType, n) if comparedPolyTypes contains pt =>
364+
case t @ TypeParamRef(pt: TypeLambda, n) if comparedTypeLambdas contains pt =>
365365
val effectiveVariance = if (fromBelow) -variance else variance
366366
val bounds = pt.paramInfos(n)
367367
if (effectiveVariance > 0) bounds.lo

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,17 +112,17 @@ import OrderingConstraint._
112112
* @param boundsMap a map from TypeLambda to arrays.
113113
* Each array contains twice the number of entries as there a type parameters
114114
* in the TypeLambda. The first half of the array contains the type bounds that constrain the
115-
* polytype's type parameters. The second half might contain type variables that
115+
* lambda's type parameters. The second half might contain type variables that
116116
* track the corresponding parameters, or is left empty (filled with nulls).
117117
* An instantiated type parameter is represented by having its instance type in
118118
* the corresponding array entry. The dual use of arrays for poly params
119119
* and typevars is to save space and hopefully gain some speed.
120120
*
121121
* @param lowerMap a map from TypeLambdas to arrays. Each array entry corresponds
122-
* to a parameter P of the polytype; it contains all constrained parameters
122+
* to a parameter P of the type lambda; it contains all constrained parameters
123123
* Q that are known to be smaller than P, i.e. Q <: P.
124124
* @param upperMap a map from TypeLambdas to arrays. Each array entry corresponds
125-
* to a parameter P of the polytype; it contains all constrained parameters
125+
* to a parameter P of the type lambda; it contains all constrained parameters
126126
* Q that are known to be greater than P, i.e. P <: Q.
127127
*/
128128
class OrderingConstraint(private val boundsMap: ParamBounds,
@@ -456,7 +456,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
456456

457457
// ---------- Exploration --------------------------------------------------------
458458

459-
def domainPolys: List[TypeLambda] = boundsMap.keys
459+
def domainLambdas: List[TypeLambda] = boundsMap.keys
460460

461461
def domainParams: List[TypeParamRef] =
462462
for {
@@ -584,7 +584,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
584584
val uninstVarsText = " uninstVars = " ~
585585
Text(uninstVars map (_.toText(printer)), ", ") ~ ";"
586586
val constrainedText =
587-
" constrained types = " ~ Text(domainPolys map (_.toText(printer)), ", ")
587+
" constrained types = " ~ Text(domainLambdas map (_.toText(printer)), ", ")
588588
val boundsText =
589589
" bounds = " ~ {
590590
val assocs =
@@ -614,8 +614,8 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
614614
case _ =>" := " + tp
615615
}
616616
val constrainedText =
617-
" constrained types = " + domainPolys.mkString("\n")
618-
val boundsText =
617+
" constrained types = " + domainLambdas.mkString("\n")
618+
val boundsText = domainLambdas
619619
" bounds = " + {
620620
val assocs =
621621
for (param <- domainParams)

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
package dotty.tools.dotc.core
22

3-
import Names.TypeName
3+
import Names.Name
44
import Contexts.Context
5-
import Types.{Type, TypeBounds}
5+
import Types.Type
66

77
/** A common super trait of Symbol and LambdaParam.
88
* Used to capture the attributes of type parameters which can be implemented as either.
99
*/
1010
trait ParamInfo {
1111

12+
type ThisName <: Name
13+
1214
/** Is this the info of a type parameter? Will return `false` for symbols
1315
* that are not type parameters.
1416
*/
1517
def isTypeParam(implicit ctx: Context): Boolean
1618

1719
/** The name of the type parameter */
18-
def paramName(implicit ctx: Context): TypeName
20+
def paramName(implicit ctx: Context): ThisName
1921

2022
/** The info of the type parameter */
2123
def paramInfo(implicit ctx: Context): Type
@@ -37,4 +39,8 @@ trait ParamInfo {
3739

3840
/** A type that refers to the parameter */
3941
def paramRef(implicit ctx: Context): Type
42+
}
43+
44+
object ParamInfo {
45+
type Of[N] = ParamInfo { type ThisName = N }
4046
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@ object SymDenotations {
11411141
case tp: NamedType => hasSkolems(tp.prefix)
11421142
case tp: RefinedType => hasSkolems(tp.parent) || hasSkolems(tp.refinedInfo)
11431143
case tp: RecType => hasSkolems(tp.parent)
1144-
case tp: PolyType => tp.paramInfos.exists(hasSkolems) || hasSkolems(tp.resType)
1144+
case tp: TypeLambda => tp.paramInfos.exists(hasSkolems) || hasSkolems(tp.resType)
11451145
case tp: MethodType => tp.paramInfos.exists(hasSkolems) || hasSkolems(tp.resType)
11461146
case tp: ExprType => hasSkolems(tp.resType)
11471147
case tp: HKApply => hasSkolems(tp.tycon) || tp.args.exists(hasSkolems)

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,11 +513,11 @@ object Symbols {
513513
*/
514514
def pos: Position = if (coord.isPosition) coord.toPosition else NoPosition
515515

516-
// ParamInfo methods
516+
// ParamInfo types and methods
517517
def isTypeParam(implicit ctx: Context) = denot.is(TypeParam)
518-
def paramName(implicit ctx: Context) = name.asTypeName
518+
def paramName(implicit ctx: Context) = name.asInstanceOf[ThisName]
519519
def paramInfo(implicit ctx: Context) = denot.info.bounds
520-
def paramInfoAsSeenFrom(pre: Type)(implicit ctx: Context) = pre.memberInfo(this)
520+
def paramInfoAsSeenFrom(pre: Type)(implicit ctx: Context) = pre.memberInfo(this).bounds
521521
def paramInfoOrCompleter(implicit ctx: Context): Type = denot.infoOrCompleter
522522
def paramVariance(implicit ctx: Context) = denot.variance
523523
def paramRef(implicit ctx: Context) = denot.typeRef

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

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import java.util.NoSuchElementException
2020

2121
object TypeApplications {
2222

23+
type TypeParamInfo = ParamInfo.Of[TypeName]
24+
2325
/** Assert type is not a TypeBounds instance and return it unchanged */
2426
val noBounds = (tp: Type) => tp match {
2527
case tp: TypeBounds => throw new AssertionError("no TypeBounds allowed")
@@ -46,14 +48,14 @@ object TypeApplications {
4648

4749
/** Does the variance of type parameter `tparam1` conform to the variance of type parameter `tparam2`?
4850
*/
49-
def varianceConforms(tparam1: ParamInfo, tparam2: ParamInfo)(implicit ctx: Context): Boolean =
51+
def varianceConforms(tparam1: TypeParamInfo, tparam2: TypeParamInfo)(implicit ctx: Context): Boolean =
5052
varianceConforms(tparam1.paramVariance, tparam2.paramVariance)
5153

5254
/** Do the variances of type parameters `tparams1` conform to the variances
5355
* of corresponding type parameters `tparams2`?
5456
* This is only the case of `tparams1` and `tparams2` have the same length.
5557
*/
56-
def variancesConform(tparams1: List[ParamInfo], tparams2: List[ParamInfo])(implicit ctx: Context): Boolean =
58+
def variancesConform(tparams1: List[TypeParamInfo], tparams2: List[TypeParamInfo])(implicit ctx: Context): Boolean =
5759
tparams1.corresponds(tparams2)(varianceConforms)
5860

5961
/** Extractor for
@@ -72,7 +74,7 @@ object TypeApplications {
7274
}
7375

7476
def unapply(tp: Type)(implicit ctx: Context): Option[TypeRef] = tp match {
75-
case tp @ PolyType(tparams, AppliedType(fn: TypeRef, args)) if (args == tparams.map(_.toArg)) => Some(fn)
77+
case tp @ PolyType/*###*/(tparams, AppliedType(fn: TypeRef, args)) if (args == tparams.map(_.toArg)) => Some(fn)
7678
case _ => None
7779
}
7880
}
@@ -95,7 +97,7 @@ object TypeApplications {
9597
refinements = rt :: refinements
9698
tycon = rt.parent.stripTypeVar
9799
}
98-
def collectArgs(tparams: List[ParamInfo],
100+
def collectArgs(tparams: List[TypeParamInfo],
99101
refinements: List[RefinedType],
100102
argBuf: mutable.ListBuffer[Type]): Option[(Type, List[Type])] = refinements match {
101103
case Nil if tparams.isEmpty && argBuf.nonEmpty =>
@@ -116,7 +118,7 @@ object TypeApplications {
116118

117119
/** Adapt all arguments to possible higher-kinded type parameters using etaExpandIfHK
118120
*/
119-
def EtaExpandIfHK(tparams: List[ParamInfo], args: List[Type])(implicit ctx: Context): List[Type] =
121+
def EtaExpandIfHK(tparams: List[TypeParamInfo], args: List[Type])(implicit ctx: Context): List[Type] =
120122
if (tparams.isEmpty) args
121123
else args.zipWithConserve(tparams)((arg, tparam) => arg.EtaExpandIfHK(tparam.paramInfoOrCompleter))
122124

@@ -159,7 +161,7 @@ object TypeApplications {
159161
* result type. Using this mode, we can guarantee that `appliedTo` will never
160162
* produce a higher-kinded application with a type lambda as type constructor.
161163
*/
162-
class Reducer(tycon: PolyType, args: List[Type])(implicit ctx: Context) extends TypeMap {
164+
class Reducer(tycon: TypeLambda, args: List[Type])(implicit ctx: Context) extends TypeMap {
163165
private var available = (0 until args.length).toSet
164166
var allReplaced = true
165167
def hasWildcardArg(p: TypeParamRef) =
@@ -208,11 +210,11 @@ class TypeApplications(val self: Type) extends AnyVal {
208210
* with the bounds on its hk args. See `LambdaAbstract`, where these
209211
* types get introduced, and see `isBoundedLambda` below for the test.
210212
*/
211-
final def typeParams(implicit ctx: Context): List[ParamInfo] = /*>|>*/ track("typeParams") /*<|<*/ {
213+
final def typeParams(implicit ctx: Context): List[TypeParamInfo] = /*>|>*/ track("typeParams") /*<|<*/ {
212214
self match {
213215
case self: ClassInfo =>
214216
self.cls.typeParams
215-
case self: PolyType =>
217+
case self: TypeLambda =>
216218
self.typeParams
217219
case self: TypeRef =>
218220
val tsym = self.symbol
@@ -235,7 +237,7 @@ class TypeApplications(val self: Type) extends AnyVal {
235237
}
236238

237239
/** If `self` is a higher-kinded type, its type parameters, otherwise Nil */
238-
final def hkTypeParams(implicit ctx: Context): List[ParamInfo] =
240+
final def hkTypeParams(implicit ctx: Context): List[TypeParamInfo] =
239241
if (isHK) typeParams else Nil
240242

241243
/** If `self` is a generic class, its type parameter symbols, otherwise Nil */
@@ -250,7 +252,7 @@ class TypeApplications(val self: Type) extends AnyVal {
250252
def isHK(implicit ctx: Context): Boolean = self.dealias match {
251253
case self: TypeRef => self.info.isHK
252254
case self: RefinedType => false
253-
case self: PolyType => true
255+
case self: TypeLambda => true
254256
case self: SingletonType => false
255257
case self: TypeVar =>
256258
// Using `origin` instead of `underlying`, as is done for typeParams,
@@ -273,16 +275,9 @@ class TypeApplications(val self: Type) extends AnyVal {
273275
*
274276
* type T[X] = U becomes type T = [X] -> U
275277
* type T[X] >: L <: U becomes type T >: L <: ([X] -> U)
276-
*
277-
* TODO: Handle parameterized lower bounds
278278
*/
279-
def LambdaAbstract(tparams: List[ParamInfo])(implicit ctx: Context): Type = {
280-
def nameWithVariance(tparam: ParamInfo) =
281-
tparam.paramName.withVariance(tparam.paramVariance)
282-
def expand(tp: Type) =
283-
PolyType(tparams.map(nameWithVariance))(
284-
tl => tparams.map(tparam => tl.lifted(tparams, tparam.paramInfo).bounds),
285-
tl => tl.lifted(tparams, tp))
279+
def LambdaAbstract(tparams: List[TypeParamInfo])(implicit ctx: Context): Type = {
280+
def expand(tp: Type) = PolyType/*HKTypeLambda*/.fromParams(tparams, tp)
286281
if (tparams.isEmpty) self
287282
else self match {
288283
case self: TypeAlias =>
@@ -362,10 +357,10 @@ class TypeApplications(val self: Type) extends AnyVal {
362357
if (hkParams.isEmpty) self
363358
else {
364359
def adaptArg(arg: Type): Type = arg match {
365-
case arg @ PolyType(tparams, body) if
360+
case arg @ PolyType(tparams, body) if /*###*/
366361
!tparams.corresponds(hkParams)(_.paramVariance == _.paramVariance) &&
367362
tparams.corresponds(hkParams)(varianceConforms) =>
368-
PolyType(
363+
PolyType(/*###*/
369364
(tparams, hkParams).zipped.map((tparam, hkparam) =>
370365
tparam.paramName.withVariance(hkparam.paramVariance)))(
371366
tl => arg.paramInfos.map(_.subst(arg, tl).bounds),
@@ -409,7 +404,7 @@ class TypeApplications(val self: Type) extends AnyVal {
409404
val dealiased = stripped.safeDealias
410405
if (args.isEmpty || ctx.erasedTypes) self
411406
else dealiased match {
412-
case dealiased: PolyType =>
407+
case dealiased: TypeLambda =>
413408
def tryReduce =
414409
if (!args.exists(_.isInstanceOf[TypeBounds])) {
415410
val followAlias = Config.simplifyApplications && {

0 commit comments

Comments
 (0)