aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-06-29 09:50:27 +0200
committerMartin Odersky <odersky@gmail.com>2016-07-11 13:35:06 +0200
commit6bd7ba9ea4484ee2065dd16077cba6c26b2050d9 (patch)
tree7b13e292f072fed02e0ba9a8a431eef92f71cf57 /src
parenta23c1a476296a25566d7aa08de676a1217b243cb (diff)
downloaddotty-6bd7ba9ea4484ee2065dd16077cba6c26b2050d9.tar.gz
dotty-6bd7ba9ea4484ee2065dd16077cba6c26b2050d9.tar.bz2
dotty-6bd7ba9ea4484ee2065dd16077cba6c26b2050d9.zip
Remove refinement encoding of hk types
Remove the code that implemented the encoding of hk types using refinements. Drop the notion that RefinedTypes can be type parameters. This is no longer true under the new representation. Also, refactoring MemberBinding -> TypeParamInfo
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/config/Config.scala2
-rw-r--r--src/dotty/tools/dotc/core/ConstraintHandling.scala2
-rw-r--r--src/dotty/tools/dotc/core/MemberBinding.scala35
-rw-r--r--src/dotty/tools/dotc/core/NameOps.scala15
-rw-r--r--src/dotty/tools/dotc/core/StdNames.scala6
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala12
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala344
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala175
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala3
-rw-r--r--src/dotty/tools/dotc/core/TypeParamInfo.scala29
-rw-r--r--src/dotty/tools/dotc/core/Types.scala82
-rw-r--r--src/dotty/tools/dotc/core/tasty/TreePickler.scala2
-rw-r--r--src/dotty/tools/dotc/printing/PlainPrinter.scala2
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala30
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala18
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala4
-rw-r--r--src/dotty/tools/dotc/typer/Variances.scala4
17 files changed, 112 insertions, 653 deletions
diff --git a/src/dotty/tools/dotc/config/Config.scala b/src/dotty/tools/dotc/config/Config.scala
index cd2b7ea4b..eba42e881 100644
--- a/src/dotty/tools/dotc/config/Config.scala
+++ b/src/dotty/tools/dotc/config/Config.scala
@@ -10,8 +10,6 @@ object Config {
final val checkCacheMembersNamed = false
- final val newHK = true
-
/** When updating a constraint bound, check that the constrained parameter
* does not appear at the top-level of either of its bounds.
*/
diff --git a/src/dotty/tools/dotc/core/ConstraintHandling.scala b/src/dotty/tools/dotc/core/ConstraintHandling.scala
index 44b6abe12..ace441566 100644
--- a/src/dotty/tools/dotc/core/ConstraintHandling.scala
+++ b/src/dotty/tools/dotc/core/ConstraintHandling.scala
@@ -286,8 +286,6 @@ trait ConstraintHandling {
if (!addParamBound(bound)) NoType
else if (fromBelow) defn.NothingType
else defn.AnyType
- case bound: RefinedType if !Config.newHK =>
- bound.normalizeHkApplyOLD
case _ =>
bound
}
diff --git a/src/dotty/tools/dotc/core/MemberBinding.scala b/src/dotty/tools/dotc/core/MemberBinding.scala
deleted file mode 100644
index bff8b30a0..000000000
--- a/src/dotty/tools/dotc/core/MemberBinding.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-package dotty.tools.dotc.core
-
-import Names.Name
-import Contexts.Context
-import Types.{Type, TypeBounds}
-
-/** A common super trait of Symbol and Refinement.
- * Used to capture the attributes of type parameters
- * which can be implemented as either symbols or refinements.
- * TODO: Rename (TypeParamInfo?)
- */
-trait MemberBinding {
-
- /** Does this binding represent a type parameter?
- * Only in that case the rest of the binding's methods are significant.
- */
- def isTypeParam(implicit ctx: Context): Boolean
-
- /** The name of the member */
- def memberName(implicit ctx: Context): Name
-
- /** The info of the member */
- def memberBounds(implicit ctx: Context): TypeBounds
-
- /** The info of the member as seen from a prefix type.
- * This can be different from `memberInfo` if the binding
- * is a type symbol of a class.
- */
- def memberBoundsAsSeenFrom(pre: Type)(implicit ctx: Context): TypeBounds
-
- /** The variance of the type parameter
- * @pre: isTypeParam = true
- */
- def memberVariance(implicit ctx: Context): Int
-} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala
index 120540dc7..f5e0eb8cd 100644
--- a/src/dotty/tools/dotc/core/NameOps.scala
+++ b/src/dotty/tools/dotc/core/NameOps.scala
@@ -101,21 +101,6 @@ object NameOps {
name.length > 0 && name.last == '=' && name.head != '=' && isOperatorPart(name.head)
}
- /** Is this the name of a higher-kinded type parameter of a Lambda? */
- def isHkArgNameOLD =
- name.length > 0 &&
- name.head == tpnme.hkArgPrefixHeadOLD &&
- name.startsWith(tpnme.hkArgPrefixOLD) && {
- val digits = name.drop(tpnme.hkArgPrefixLengthOLD)
- digits.length <= 4 && digits.forall(_.isDigit)
- }
-
- /** The index of the higher-kinded type parameter with this name.
- * Pre: isLambdaArgName.
- */
- def hkArgIndexOLD: Int =
- name.drop(tpnme.hkArgPrefixLengthOLD).toString.toInt
-
/** If the name ends with $nn where nn are
* all digits, strip the $ and the digits.
* Otherwise return the argument.
diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala
index 0adf80d8f..778d13cab 100644
--- a/src/dotty/tools/dotc/core/StdNames.scala
+++ b/src/dotty/tools/dotc/core/StdNames.scala
@@ -529,10 +529,6 @@ object StdNames {
val synthSwitch: N = "$synthSwitch"
- val hkArgPrefixOLD: N = "$hk"
- val hkArgPrefixHeadOLD: Char = hkArgPrefixOLD.head
- val hkArgPrefixLengthOLD: Int = hkArgPrefixOLD.length
-
// unencoded operators
object raw {
final val AMP : N = "&"
@@ -746,8 +742,6 @@ object StdNames {
def syntheticLambdaParamNames(num: Int): List[TypeName] =
(0 until num).map(syntheticLambdaParamName)(breakOut)
- def hkArgOLD(n: Int): TypeName = hkArgPrefixOLD ++ n.toString
-
final val Conforms = encode("<:<")
}
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index c7eb54812..df8bc8116 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -367,7 +367,7 @@ object Symbols {
* @param coord The coordinates of the symbol (a position or an index)
* @param id A unique identifier of the symbol (unique per ContextBase)
*/
- class Symbol private[Symbols] (val coord: Coord, val id: Int) extends DotClass with MemberBinding with printing.Showable {
+ class Symbol private[Symbols] (val coord: Coord, val id: Int) extends DotClass with TypeParamInfo with printing.Showable {
type ThisName <: Name
@@ -489,12 +489,12 @@ object Symbols {
*/
def pos: Position = if (coord.isPosition) coord.toPosition else NoPosition
- // MemberBinding methods
+ // TypeParamInfo methods
def isTypeParam(implicit ctx: Context) = denot.is(TypeParam)
- def memberName(implicit ctx: Context): Name = name
- def memberBounds(implicit ctx: Context) = denot.info.bounds
- def memberBoundsAsSeenFrom(pre: Type)(implicit ctx: Context) = pre.memberInfo(this).bounds
- def memberVariance(implicit ctx: Context) = denot.variance
+ def paramName(implicit ctx: Context): Name = name
+ def paramBounds(implicit ctx: Context) = denot.info.bounds
+ def paramBoundsAsSeenFrom(pre: Type)(implicit ctx: Context) = pre.memberInfo(this).bounds
+ def paramVariance(implicit ctx: Context) = denot.variance
// -------- Printing --------------------------------------------------------
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index e989e42b7..a09039521 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -46,67 +46,16 @@ object TypeApplications {
/** Does the variance of type parameter `tparam1` conform to the variance of type parameter `tparam2`?
*/
- def varianceConforms(tparam1: MemberBinding, tparam2: MemberBinding)(implicit ctx: Context): Boolean =
- varianceConforms(tparam1.memberVariance, tparam2.memberVariance)
+ def varianceConforms(tparam1: TypeParamInfo, tparam2: TypeParamInfo)(implicit ctx: Context): Boolean =
+ varianceConforms(tparam1.paramVariance, tparam2.paramVariance)
/** Doe the variances of type parameters `tparams1` conform to the variances
* of corresponding type parameters `tparams2`?
* This is only the case of `tparams1` and `tparams2` have the same length.
*/
- def variancesConform(tparams1: List[MemberBinding], tparams2: List[MemberBinding])(implicit ctx: Context): Boolean =
+ def variancesConform(tparams1: List[TypeParamInfo], tparams2: List[TypeParamInfo])(implicit ctx: Context): Boolean =
tparams1.corresponds(tparams2)(varianceConforms)
- def fallbackTypeParamsOLD(variances: List[Int])(implicit ctx: Context): List[MemberBinding] = {
- def memberBindings(vs: List[Int]): Type = vs match {
- case Nil => NoType
- case v :: vs1 =>
- RefinedType(
- memberBindings(vs1),
- tpnme.hkArgOLD(vs1.length),
- TypeBounds.empty.withBindingKind(BindingKind.fromVariance(v)))
- }
- def decompose(t: Type, acc: List[MemberBinding]): List[MemberBinding] = t match {
- case t: RefinedType => decompose(t.parent, t :: acc)
- case NoType => acc
- }
- decompose(memberBindings(variances), Nil)
- }
-
- /** Extractor for
- *
- * [v1 X1: B1, ..., vn Xn: Bn] -> T
- * ==>
- * ([X_i := this.$hk_i] T) { type v_i $hk_i: (new)B_i }
- */
- object TypeLambdaOLD {
- def apply(argBindingFns: List[RecType => TypeBounds],
- bodyFn: RecType => Type)(implicit ctx: Context): Type = {
- val argNames = argBindingFns.indices.toList.map(tpnme.hkArgOLD)
- var idx = 0
- RecType.closeOver(rt =>
- (bodyFn(rt) /: argBindingFns) { (parent, argBindingFn) =>
- val res = RefinedType(parent, tpnme.hkArgOLD(idx), argBindingFn(rt))
- idx += 1
- res
- })
- }
-
- def unapply(tp: Type)(implicit ctx: Context): Option[( /*List[Int], */ List[TypeBounds], Type)] = {
- def decompose(t: Type, acc: List[TypeBounds]): (List[TypeBounds], Type) = t match {
- case t @ RefinedType(p, rname, rinfo: TypeBounds) if t.isTypeParam =>
- decompose(p, rinfo.bounds :: acc)
- case t: RecType =>
- decompose(t.parent, acc)
- case _ =>
- (acc, t)
- }
- decompose(tp, Nil) match {
- case (Nil, _) => None
- case x => Some(x)
- }
- }
- }
-
/** Extractor for
*
* [v1 X1: B1, ..., vn Xn: Bn] -> C[X1, ..., Xn]
@@ -118,33 +67,14 @@ object TypeApplications {
*/
object EtaExpansion {
def apply(tycon: Type)(implicit ctx: Context) = {
- if (Config.newHK) assert(tycon.typeParams.nonEmpty, tycon)
- else assert(tycon.isEtaExpandableOLD)
+ assert(tycon.typeParams.nonEmpty, tycon)
tycon.EtaExpand(tycon.typeParamSymbols)
}
- def unapply(tp: Type)(implicit ctx: Context): Option[TypeRef] =
- if (Config.newHK)
- tp match {
- case tp @ TypeLambda(tparams, AppliedType(fn: TypeRef, args))
- if (args == tparams.map(_.toArg)) => Some(fn)
- case _ => None
- }
- else {
- def argsAreForwarders(args: List[Type], n: Int): Boolean = args match {
- case Nil =>
- n == 0
- case TypeRef(RecThis(rt), sel) :: args1 if false =>
- rt.eq(tp) && sel == tpnme.hkArgOLD(n - 1) && argsAreForwarders(args1, n - 1)
- case _ =>
- false
- }
- tp match {
- case TypeLambdaOLD(argBounds, AppliedType(fn: TypeRef, args))
- if argsAreForwarders(args, tp.typeParams.length) => Some(fn)
- case _ => None
- }
- }
+ def unapply(tp: Type)(implicit ctx: Context): Option[TypeRef] = tp match {
+ case tp @ TypeLambda(tparams, AppliedType(fn: TypeRef, args)) if (args == tparams.map(_.toArg)) => Some(fn)
+ case _ => None
+ }
}
/** Extractor for type application T[U_1, ..., U_n]. This is the refined type
@@ -165,13 +95,13 @@ object TypeApplications {
refinements = rt :: refinements
tycon = rt.parent.stripTypeVar
}
- def collectArgs(tparams: List[MemberBinding],
+ def collectArgs(tparams: List[TypeParamInfo],
refinements: List[RefinedType],
argBuf: mutable.ListBuffer[Type]): Option[(Type, List[Type])] = refinements match {
case Nil if tparams.isEmpty && argBuf.nonEmpty =>
Some((tycon, argBuf.toList))
case RefinedType(_, rname, rinfo) :: refinements1
- if tparams.nonEmpty && rname == tparams.head.memberName =>
+ if tparams.nonEmpty && rname == tparams.head.paramName =>
collectArgs(tparams.tail, refinements1, argBuf += rinfo.argInfo)
case _ =>
None
@@ -186,44 +116,16 @@ object TypeApplications {
/** Adapt all arguments to possible higher-kinded type parameters using etaExpandIfHK
*/
- def etaExpandIfHK(tparams: List[MemberBinding], args: List[Type])(implicit ctx: Context): List[Type] =
+ def etaExpandIfHK(tparams: List[TypeParamInfo], args: List[Type])(implicit ctx: Context): List[Type] =
if (tparams.isEmpty) args
else {
- def bounds(tparam: MemberBinding) = tparam match {
+ def bounds(tparam: TypeParamInfo) = tparam match {
case tparam: Symbol => tparam.infoOrCompleter
- case tparam: RefinedType if !Config.newHK => tparam.memberBounds
- case tparam: LambdaParam => tparam.memberBounds
+ case tparam: LambdaParam => tparam.paramBounds
}
args.zipWithConserve(tparams)((arg, tparam) => arg.etaExpandIfHK(bounds(tparam)))
}
- /** The references `<rt>.this.$hk0, ..., <rt>.this.$hk<n-1>`. */
- def argRefsOLD(rt: RecType, n: Int)(implicit ctx: Context) =
- List.range(0, n).map(i => RecThis(rt).select(tpnme.hkArgOLD(i)))
-
- private class InstMapOLD(fullType: Type)(implicit ctx: Context) extends TypeMap {
- var localRecs: Set[RecType] = Set.empty
- var keptRefs: Set[Name] = Set.empty
- var tyconIsHK: Boolean = true
- def apply(tp: Type): Type = tp match {
- case tp @ TypeRef(RecThis(rt), sel) if sel.isHkArgNameOLD && localRecs.contains(rt) =>
- fullType.member(sel).info match {
- case TypeAlias(alias) => apply(alias)
- case _ => keptRefs += sel; tp
- }
- case tp: TypeVar if !tp.inst.exists =>
- val bounds = tp.instanceOpt.orElse(ctx.typeComparer.bounds(tp.origin))
- bounds.foreachPart {
- case TypeRef(RecThis(rt), sel) if sel.isHkArgNameOLD && localRecs.contains(rt) =>
- keptRefs += sel
- case _ =>
- }
- tp
- case _ =>
- mapOver(tp)
- }
- }
-
/** A type map that tries to reduce a (part of) the result type of the type lambda `tycon`
* with the given `args`(some of which are wildcard arguments represented by type bounds).
* Non-wildcard arguments are substituted everywhere as usual. A wildcard argument
@@ -281,7 +183,7 @@ class TypeApplications(val self: Type) extends AnyVal {
* with the bounds on its hk args. See `LambdaAbstract`, where these
* types get introduced, and see `isBoundedLambda` below for the test.
*/
- final def typeParams(implicit ctx: Context): List[MemberBinding] = /*>|>*/ track("typeParams") /*<|<*/ {
+ final def typeParams(implicit ctx: Context): List[TypeParamInfo] = /*>|>*/ track("typeParams") /*<|<*/ {
self match {
case self: ClassInfo =>
self.cls.typeParams
@@ -293,8 +195,7 @@ class TypeApplications(val self: Type) extends AnyVal {
else if (!tsym.isCompleting) tsym.info.typeParams
else Nil
case self: RefinedType =>
- val precedingParams = self.parent.typeParams.filterNot(_.memberName == self.refinedName)
- if (self.isTypeParam) precedingParams :+ self else precedingParams
+ self.parent.typeParams.filterNot(_.paramName == self.refinedName)
case self: RecType =>
self.parent.typeParams
case _: HKApply | _: SingletonType =>
@@ -309,7 +210,7 @@ class TypeApplications(val self: Type) extends AnyVal {
}
/** If `self` is a higher-kinded type, its type parameters $hk_i, otherwise Nil */
- final def hkTypeParams(implicit ctx: Context): List[MemberBinding] =
+ final def hkTypeParams(implicit ctx: Context): List[TypeParamInfo] =
if (isHK) typeParams else Nil
/** If `self` is a generic class, its type parameter symbols, otherwise Nil */
@@ -384,7 +285,7 @@ class TypeApplications(val self: Type) extends AnyVal {
/** Is self type higher-kinded (i.e. of kind != "*")? */
def isHK(implicit ctx: Context): Boolean = self.dealias match {
case self: TypeRef => self.info.isHK
- case self: RefinedType => !Config.newHK && self.isTypeParam
+ case self: RefinedType => false
case self: TypeLambda => true
case self: HKApply => false
case self: SingletonType => false
@@ -410,8 +311,7 @@ class TypeApplications(val self: Type) extends AnyVal {
if (!tsym.isCompleting || tsym.isAliasType) tsym.info.knownHK
else 0
}
- case self: RefinedType =>
- if (!Config.newHK && self.isTypeParam) 1 else -1
+ case self: RefinedType => -1
case self: TypeLambda => 1
case self: HKApply => -1
case self: SingletonType => -1
@@ -423,12 +323,6 @@ class TypeApplications(val self: Type) extends AnyVal {
case _ => -1
}
- /** is receiver a higher-kinded application? */
- def isHKApplyOLD(implicit ctx: Context): Boolean = self match {
- case self @ RefinedType(_, name, _) => name.isHkArgNameOLD && !self.isTypeParam
- case _ => false
- }
-
/** True if it can be determined without forcing that the class symbol
* of this application exists. Equivalent to
*
@@ -457,25 +351,6 @@ class TypeApplications(val self: Type) extends AnyVal {
self
}
- /** Replace references to type parameters with references to hk arguments `this.$hk_i`
- * Care is needed not to cause cyclic reference errors, hence `SafeSubstMap`.
- */
- def recursifyOLD[T <: Type](tparams: List[MemberBinding])(implicit ctx: Context): RecType => T =
- tparams match {
- case (_: Symbol) :: _ =>
- (rt: RecType) =>
- new ctx.SafeSubstMap(tparams.asInstanceOf[List[Symbol]], argRefsOLD(rt, tparams.length))
- .apply(self).asInstanceOf[T]
- case _ =>
- def mapRefs(rt: RecType) = new TypeMap {
- def apply(t: Type): Type = t match {
- case rthis: RecThis if tparams contains rthis.binder.parent => RecThis(rt)
- case _ => mapOver(t)
- }
- }
- mapRefs(_).apply(self).asInstanceOf[T]
- }
-
/** Lambda abstract `self` with given type parameters. Examples:
*
* type T[X] = U becomes type T = [X] -> U
@@ -485,124 +360,18 @@ class TypeApplications(val self: Type) extends AnyVal {
*/
def LambdaAbstract(tparams: List[Symbol])(implicit ctx: Context): Type = {
def expand(tp: Type) =
- if (Config.newHK)
- TypeLambda(
- tpnme.syntheticLambdaParamNames(tparams.length), tparams.map(_.variance))(
- tl => tparams.map(tparam => tl.lifted(tparams, tparam.info).bounds),
- tl => tl.lifted(tparams, tp))
- else
- TypeLambdaOLD(
- tparams.map(tparam =>
- tparam.memberBoundsAsSeenFrom(self)
- .withBindingKind(BindingKind.fromVariance(tparam.variance))
- .recursifyOLD(tparams)),
- tp.recursifyOLD(tparams))
-
+ TypeLambda(
+ tpnme.syntheticLambdaParamNames(tparams.length), tparams.map(_.variance))(
+ tl => tparams.map(tparam => tl.lifted(tparams, tparam.info).bounds),
+ tl => tl.lifted(tparams, tp))
assert(!isHK, self)
- if (Config.newHK) self match {
+ self match {
case self: TypeAlias =>
self.derivedTypeAlias(expand(self.alias))
case self @ TypeBounds(lo, hi) =>
self.derivedTypeBounds(lo, expand(hi))
case _ => expand(self)
}
- else self match {
- case self: TypeAlias =>
- self.derivedTypeAlias(expand(self.alias.normalizeHkApplyOLD))
- case self @ TypeBounds(lo, hi) =>
- self.derivedTypeBounds(lo, expand(hi.normalizeHkApplyOLD))
- case _ => expand(self)
- }
- }
-
- /** If `self` is a * type, perform the following rewritings:
- *
- * 1. For every occurrence of `z.$hk_i`, where `z` is a RecThis type that refers
- * to some recursive type in `self`, if the member of `self.hk$i` has an alias
- * type `= U`:
- *
- * z.$hk_i --> U
- *
- * 2. For every top-level binding `type A = z.$hk_i$, where `z` is a RecThis type that refers
- * to some recursive type in `self`, if the member of `self` has bounds `S..U`:
- *
- * type A = z.$hk_i --> type A >: S <: U
- *
- * 3. If the type constructor preceding all bindings is a * type, delete every top-level
- * binding `{ type $hk_i ... }` where `$hk_i` does not appear in the prefix of the binding.
- * I.e.
- *
- * T { type $hk_i ... } --> T
- *
- * If `$hk_i` does not appear in `T`.
- *
- * A binding is top-level if it can be reached by
- *
- * - following aliases unless the type is a LazyRef
- * (need to keep cycle breakers around, see i974.scala)
- * - dropping refinements and rec-types
- * - going from a wildcard type to its upper bound
- */
- def normalizeHkApplyOLD(implicit ctx: Context): Type = self.strictDealias match {
- case self1 @ RefinedType(_, rname, _) if rname.isHkArgNameOLD && self1.typeParams.isEmpty =>
- val inst = new InstMapOLD(self)
-
- def instTop(tp: Type): Type = tp.strictDealias match {
- case tp: RecType =>
- inst.localRecs += tp
- tp.rebind(instTop(tp.parent))
- case tp @ RefinedType(parent, rname, rinfo) =>
- rinfo match {
- case TypeAlias(TypeRef(RecThis(rt), sel)) if sel.isHkArgNameOLD && inst.localRecs.contains(rt) =>
- val bounds @ TypeBounds(_, _) = self.member(sel).info
- instTop(tp.derivedRefinedType(parent, rname, bounds.withBindingKind(NoBinding)))
- case _ =>
- val parent1 = instTop(parent)
- if (rname.isHkArgNameOLD &&
- !inst.tyconIsHK &&
- !inst.keptRefs.contains(rname)) parent1
- else tp.derivedRefinedType(parent1, rname, inst(rinfo))
- }
- case tp @ WildcardType(bounds @ TypeBounds(lo, hi)) =>
- tp.derivedWildcardType(bounds.derivedTypeBounds(inst(lo), instTop(hi)))
- case tp: LazyRef =>
- instTop(tp.ref)
- case tp =>
- inst.tyconIsHK = tp.isHK
- inst(tp)
- }
-
- def isLazy(tp: Type): Boolean = tp.strictDealias match {
- case tp: RefinedOrRecType => isLazy(tp.parent)
- case tp @ WildcardType(bounds @ TypeBounds(lo, hi)) => isLazy(hi)
- case tp: LazyRef => true
- case _ => false
- }
-
- val reduced =
- if (isLazy(self1)) {
- // A strange dance is needed here to make 974.scala compile.
- val res = LazyRef(() => instTop(self))
- res.ref // without this line, pickling 974.scala fails with an assertion error
- // saying that we address a RecThis outside its Rec (in the case of RecThis of pickleNewType)
- res // without this line, typing 974.scala gives a stackoverflow in asSeenFrom.
- }
- else instTop(self)
- if (reduced ne self) {
- hk.println(i"reduce $self --> $reduced / ${inst.tyconIsHK}")
- //hk.println(s"reduce $self --> $reduced")
- }
- reduced
- case _ => self
- }
-
- /** A type ref is eta expandable if it refers to a non-lambda class.
- * In that case we can look for parameterized base types of the type
- * to eta expand them.
- */
- def isEtaExpandableOLD(implicit ctx: Context) = self match {
- case self: TypeRef => self.symbol.isClass
- case _ => false
}
/** Convert a type constructor `TC` which has type parameters `T1, ..., Tn`
@@ -681,23 +450,12 @@ class TypeApplications(val self: Type) extends AnyVal {
else {
def adaptArg(arg: Type): Type = arg match {
case arg @ TypeLambda(tparams, body) if
- !tparams.corresponds(hkParams)(_.memberVariance == _.memberVariance) &&
+ !tparams.corresponds(hkParams)(_.paramVariance == _.paramVariance) &&
tparams.corresponds(hkParams)(varianceConforms) =>
- TypeLambda(tparams.map(_.memberName), hkParams.map(_.memberVariance))(
+ TypeLambda(tparams.map(_.paramName), hkParams.map(_.paramVariance))(
tl => arg.paramBounds.map(_.subst(arg, tl).bounds),
tl => arg.resultType.subst(arg, tl)
)
- case arg @ TypeLambdaOLD(tparamBounds, body) if
- !arg.typeParams.corresponds(hkParams)(_.memberVariance == _.memberVariance) &&
- arg.typeParams.corresponds(hkParams)(varianceConforms) =>
- def adjustVariance(bounds: TypeBounds, tparam: MemberBinding): TypeBounds =
- bounds.withBindingKind(BindingKind.fromVariance(tparam.memberVariance))
- def lift[T <: Type](tp: T): (RecType => T) = arg match {
- case rt0: RecType => tp.subst(rt0, _).asInstanceOf[T]
- case _ => (x => tp)
- }
- val adjusted = (tparamBounds, hkParams).zipped.map(adjustVariance)
- TypeLambdaOLD(adjusted.map(lift), lift(body))
case arg @ TypeAlias(alias) =>
arg.derivedTypeAlias(adaptArg(alias))
case arg @ TypeBounds(lo, hi) =>
@@ -731,16 +489,6 @@ class TypeApplications(val self: Type) extends AnyVal {
self.instantiate(args)
case EtaExpansion(self1) =>
self1.appliedTo(args)
- case TypeLambdaOLD(_, body) if !args.exists(_.isInstanceOf[TypeBounds]) =>
- def substHkArgs = new TypeMap {
- def apply(tp: Type): Type = tp match {
- case TypeRef(RecThis(rt), name) if rt.eq(self) && name.isHkArgNameOLD =>
- args(name.hkArgIndexOLD)
- case _ =>
- mapOver(tp)
- }
- }
- substHkArgs(body)
case self1: WildcardType =>
self1
case _ =>
@@ -753,12 +501,12 @@ class TypeApplications(val self: Type) extends AnyVal {
* @param args = `U1, ..., Un`
* @param tparams are assumed to be the type parameters of `T`.
*/
- final def appliedTo(args: List[Type], typParams: List[MemberBinding])(implicit ctx: Context): Type = {
- def matchParams(t: Type, tparams: List[MemberBinding], args: List[Type])(implicit ctx: Context): Type = args match {
+ final def appliedTo(args: List[Type], typParams: List[TypeParamInfo])(implicit ctx: Context): Type = {
+ def matchParams(t: Type, tparams: List[TypeParamInfo], args: List[Type])(implicit ctx: Context): Type = args match {
case arg :: args1 =>
try {
val tparam :: tparams1 = tparams
- matchParams(RefinedType(t, tparam.memberName, arg.toBounds(tparam)), tparams1, args1)
+ matchParams(RefinedType(t, tparam.paramName, arg.toBounds(tparam)), tparams1, args1)
} catch {
case ex: MatchError =>
println(s"applied type mismatch: $self with underlying ${self.underlyingIfProxy}, args = $args, typeParams = $typParams") // !!! DEBUG
@@ -790,12 +538,7 @@ class TypeApplications(val self: Type) extends AnyVal {
case _ if typParams.isEmpty || typParams.head.isInstanceOf[LambdaParam] =>
HKApply(self, args)
case dealiased =>
- matchParams(dealiased, typParams, args) match {
- case refined @ RefinedType(_, pname, _) if !Config.newHK && pname.isHkArgNameOLD =>
- refined.betaReduceOLD
- case refined =>
- refined
- }
+ matchParams(dealiased, typParams, args)
}
}
@@ -810,34 +553,21 @@ class TypeApplications(val self: Type) extends AnyVal {
* up hk type parameters matching the arguments. This is needed when unpickling
* Scala2 files such as `scala.collection.generic.Mapfactory`.
*/
- final def safeAppliedTo(args: List[Type])(implicit ctx: Context) =
- if (Config.newHK)
- self match {
- case self: TypeRef if !self.symbol.isClass && self.symbol.isCompleting =>
- HKApply(self, args)
- case _ =>
- appliedTo(args, typeParams)
- }
- else {
- val safeTypeParams = self match {
- case self: TypeRef if !self.symbol.isClass && self.symbol.isCompleting =>
- // This happens when unpickling e.g. scala$collection$generic$GenMapFactory$$CC
- ctx.warning(i"encountered F-bounded higher-kinded type parameters for ${self.symbol}; assuming they are invariant")
- fallbackTypeParamsOLD(args map alwaysZero)
- case _ =>
- typeParams
- }
- appliedTo(args, safeTypeParams)
- }
+ final def safeAppliedTo(args: List[Type])(implicit ctx: Context) = self match {
+ case self: TypeRef if !self.symbol.isClass && self.symbol.isCompleting =>
+ HKApply(self, args)
+ case _ =>
+ appliedTo(args, typeParams)
+ }
/** Turn this type, which is used as an argument for
* type parameter `tparam`, into a TypeBounds RHS
*/
- final def toBounds(tparam: MemberBinding)(implicit ctx: Context): TypeBounds = self match {
+ final def toBounds(tparam: TypeParamInfo)(implicit ctx: Context): TypeBounds = self match {
case self: TypeBounds => // this can happen for wildcard args
self
case _ =>
- val v = tparam.memberVariance
+ val v = tparam.paramVariance
/* Not neeeded.
if (v > 0 && !(tparam is Local) && !(tparam is ExpandedTypeParam)) TypeBounds.upper(self)
else if (v < 0 && !(tparam is Local) && !(tparam is ExpandedTypeParam)) TypeBounds.lower(self)
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 38b45b2b0..55a964ee9 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -364,16 +364,9 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
// This twist is needed to make collection/generic/ParFactory.scala compile
fourthTry(tp1, tp2) || compareRefinedSlow
case _ =>
- if (tp2.isTypeParam) {
- compareHkLambdaOLD(tp1, tp2) ||
- fourthTry(tp1, tp2)
- }
- else {
- compareHkApplyOLD(tp2, tp1, inOrder = false) ||
- compareRefinedSlow ||
- fourthTry(tp1, tp2) ||
- compareAliasedRefined(tp2, tp1, inOrder = false)
- }
+ compareRefinedSlow ||
+ fourthTry(tp1, tp2) ||
+ compareAliasedRefined(tp2, tp1, inOrder = false) // @@@ still needed?
}
else // fast path, in particular for refinements resulting from parameterization.
isSubRefinements(tp1w.asInstanceOf[RefinedType], tp2, skipped2) &&
@@ -399,7 +392,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
// so the bounds checking should look like this:
//
// tparams1.corresponds(tparams2)((tparam1, tparam2) =>
- // isSubType(tparam2.memberBounds.subst(tp2, tp1), tparam1.memberBounds))
+ // isSubType(tparam2.paramBounds.subst(tp2, tp1), tparam1.paramBounds))
//
// But that would invalidate a pattern such as
// `[X0 <: Number] -> Number <:< [X0] -> Any`
@@ -531,7 +524,6 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
}
isNewSubType(tp1.underlying.widenExpr, tp2) || comparePaths
case tp1: RefinedType =>
- compareHkApplyOLD(tp1, tp2, inOrder = true) ||
isNewSubType(tp1.parent, tp2) ||
compareAliasedRefined(tp1, tp2, inOrder = true)
case tp1: RecType =>
@@ -693,10 +685,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
/** Subtype test for corresponding arguments in `args1`, `args2` according to
* variances in type parameters `tparams`.
*/
- def isSubArgs(args1: List[Type], args2: List[Type], tparams: List[MemberBinding]): Boolean =
+ def isSubArgs(args1: List[Type], args2: List[Type], tparams: List[TypeParamInfo]): Boolean =
if (args1.isEmpty) args2.isEmpty
else args2.nonEmpty && {
- val v = tparams.head.memberVariance
+ val v = tparams.head.paramVariance
(v > 0 || isSubType(args2.head, args1.head)) &&
(v < 0 || isSubType(args1.head, args2.head))
}
@@ -706,7 +698,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
* - the type parameters of `B` match one-by-one the variances of `tparams`,
* - `B` satisfies predicate `p`.
*/
- private def testLifted(tp1: Type, tp2: Type, tparams: List[MemberBinding], p: Type => Boolean): Boolean = {
+ private def testLifted(tp1: Type, tp2: Type, tparams: List[TypeParamInfo], p: Type => Boolean): Boolean = {
val classBounds = tp2.classSymbols
def recur(bcs: List[ClassSymbol]): Boolean = bcs match {
case bc :: bcs1 =>
@@ -722,109 +714,6 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
recur(tp1.baseClasses)
}
- /** Handle subtype tests
- *
- * app <:< other if inOrder = true
- * other <:< app if inOrder = false
- *
- * where `app` is an hk application but `other` is not.
- *
- * As a first step, if `app` appears on the right, try to normalize it using
- * `normalizeHkApply`, if that gives a different type proceed with a regular subtype
- * test using that type instead of `app`.
- *
- * Otherwise, if `app` has constrainable poly param as type constructor,
- * perform the following steps:
- *
- * (1) If not `inOrder` then perform the next steps until they all succeed
- * for each base type of other which
- * - derives from a class bound of `app`,
- * - has the same number of type parameters as `app`
- * - has type parameter variances which conform to those of `app`.
- * If `inOrder` then perform the same steps on the original `other` type.
- *
- * (2) Try to eta expand the constructor of `other`.
- *
- * (3a) In mode `TypevarsMissConetxt` replace the projection's hk constructor parameter
- * by the eta expansion of step (2) reapplied to the projection's arguments.
- * (3b) In normal mode, try to unify the projection's hk constructor parameter with
- * the eta expansion of step(2)
- *
- * (4) If `inOrder`, test `app <: other` else test `other <: app`.
- */
- def compareHkApplyOLD(app: RefinedType, other: Type, inOrder: Boolean): Boolean = {
- def tryInfer(tp: Type): Boolean = ctx.traceIndented(i"compareHK($app, $other, inOrder = $inOrder, constr = $tp)", subtyping) {
- tp match {
- case tp: TypeVar => tryInfer(tp.underlying)
- case param: PolyParam if canConstrain(param) =>
-
- def unifyWith(liftedOther: Type): Boolean = {
- subtyping.println(i"unify with $liftedOther")
- liftedOther.typeConstructor.widen match {
- case tycon: TypeRef if tycon.isEtaExpandableOLD && tycon.typeParams.nonEmpty =>
- val (ok, app1) =
- if (ctx.mode.is(Mode.TypevarsMissContext))
- (true, EtaExpansion(tycon).appliedTo(app.argInfos))
- else
- (tryInstantiate(param, EtaExpansion(tycon)), app)
- ok &&
- (if (inOrder) isSubType(app1, other) else isSubType(other, app1))
- case _ =>
- false
- }
- }
- val hkTypeParams = param.typeParams
- subtyping.println(i"classBounds = ${app.classSymbols}")
- subtyping.println(i"base classes = ${other.baseClasses}")
- subtyping.println(i"type params = $hkTypeParams, ${app.classSymbol}")
- if (inOrder) unifyWith(other)
- else testLifted(other, app, hkTypeParams, unifyWith)
- case _ =>
- // why only handle the case where one of the sides is a typevar or poly param?
- // If the LHS is a hk application, then the normal logic already handles
- // all other cases. Indeed, say you have
- //
- // type C[T] <: List[T]
- //
- // where C is an abstract type. Then to verify `C[Int] <: List[Int]`,
- // use compareRefinedslow to get `C <: List` and verify that
- //
- // C#List$T = C$$hk0 = Int
- //
- // If the RHS is a hk application, we can also go through
- // the normal logic because lower bounds are not parameterized.
- // If were to re-introduce parameterized lower bounds of hk types
- // we'd have to add some logic to handle them here.
- false
- }
- }
- app.isHKApplyOLD && !other.isHKApplyOLD && {
- val reduced = if (inOrder) app else app.normalizeHkApplyOLD
- if (reduced ne app)
- if (inOrder) isSubType(reduced, other) else isSubType(other, reduced)
- else tryInfer(app.typeConstructor.dealias)
- }
- }
-
- /** Compare type lambda with non-lambda type. */
- def compareHkLambdaOLD(tp1: Type, tp2: RefinedType): Boolean = tp1.stripTypeVar match {
- case TypeLambdaOLD(args1, body1) =>
- //println(i"comparing $tp1 <:< $tp2")
- tp2 match {
- case TypeLambdaOLD(args2, body2) =>
- args1.corresponds(args2)((arg1, arg2) =>
- varianceConforms(BindingKind.toVariance(arg1.bindingKind),
- BindingKind.toVariance(arg2.bindingKind))) &&
- // don't compare bounds; it would go in the wrong sense anyway.
- isSubType(body1, body2)
- case _ => false
- }
- case RefinedType(parent1, _, _) =>
- compareHkLambdaOLD(parent1, tp2)
- case _ =>
- false
- }
-
/** Say we are comparing a refined type `P{type M = U}` or `P{type M >: L <: U}`.
* If P#M refers to a BaseTypeArg aliased to some other typeref P#N,
* do the same comparison with `P{type N = U}` or `P{type N >: L <: U}`, respectively.
@@ -1324,45 +1213,25 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
private def liftIfHK(tp1: Type, tp2: Type, op: (Type, Type) => Type, original: (Type, Type) => Type) = {
val tparams1 = tp1.typeParams
val tparams2 = tp2.typeParams
- if (!Config.newHK && tparams1.isEmpty || tparams2.isEmpty) op(tp1, tp2)
- else if (Config.newHK && tparams1.isEmpty)
+ if (tparams1.isEmpty)
if (tparams2.isEmpty) op(tp1, tp2)
- else original(tp1, tp2.appliedTo(tp2.typeParams.map(_.memberBoundsAsSeenFrom(tp2))))
- else if (Config.newHK && tparams2.isEmpty)
- original(tp1.appliedTo(tp1.typeParams.map(_.memberBoundsAsSeenFrom(tp1))), tp2)
- else if (!Config.newHK && (tparams1.isEmpty || tparams2.isEmpty)) op(tp1, tp2)
- else if (!Config.newHK && tparams1.length != tparams2.length) mergeConflict(tp1, tp2)
- else if (Config.newHK) {
+ else original(tp1, tp2.appliedTo(tp2.typeParams.map(_.paramBoundsAsSeenFrom(tp2))))
+ else if (tparams2.isEmpty)
+ original(tp1.appliedTo(tp1.typeParams.map(_.paramBoundsAsSeenFrom(tp1))), tp2)
+ else {
val numArgs = tparams1.length
def argRefs(tl: GenericType) = List.range(0, numArgs).map(PolyParam(tl, _))
TypeLambda(
paramNames = tpnme.syntheticLambdaParamNames(numArgs),
variances = (tparams1, tparams2).zipped.map((tparam1, tparam2) =>
- (tparam1.memberVariance + tparam2.memberVariance) / 2))(
+ (tparam1.paramVariance + tparam2.paramVariance) / 2))(
paramBoundsExp = tl => (tparams1, tparams2).zipped.map((tparam1, tparam2) =>
- tl.lifted(tparams1, tparam1.memberBoundsAsSeenFrom(tp1)).bounds &
- tl.lifted(tparams2, tparam2.memberBoundsAsSeenFrom(tp2)).bounds),
+ tl.lifted(tparams1, tparam1.paramBoundsAsSeenFrom(tp1)).bounds &
+ tl.lifted(tparams2, tparam2.paramBoundsAsSeenFrom(tp2)).bounds),
resultTypeExp = tl =>
original(tl.lifted(tparams1, tp1).appliedTo(argRefs(tl)),
tl.lifted(tparams2, tp2).appliedTo(argRefs(tl))))
}
- else {
- val bindings: List[RecType => TypeBounds] =
- (tparams1, tparams2).zipped.map { (tparam1, tparam2) =>
- val b1: RecType => TypeBounds =
- tparam1.memberBoundsAsSeenFrom(tp1).recursifyOLD(tparams1)
- val b2: RecType => TypeBounds =
- tparam2.memberBoundsAsSeenFrom(tp2).recursifyOLD(tparams2)
- (rt: RecType) => (b1(rt) & b2(rt))
- .withBindingKind(
- BindingKind.fromVariance(
- (tparam1.memberVariance + tparam2.memberVariance) / 2))
- }
- val app1: RecType => Type = rt => tp1.appliedTo(argRefsOLD(rt, tparams1.length))
- val app2: RecType => Type = rt => tp2.appliedTo(argRefsOLD(rt, tparams2.length))
- val body: RecType => Type = rt => op(app1(rt), app2(rt))
- TypeLambdaOLD(bindings, body)
- }
}
/** Try to distribute `&` inside type, detect and handle conflicts
@@ -1652,19 +1521,5 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
}
}
- override def compareHkApplyOLD(app: RefinedType, other: Type, inOrder: Boolean) =
- if (app.isHKApplyOLD)
- traceIndented(i"compareHkApply $app, $other, $inOrder, ${app.normalizeHkApplyOLD}") {
- super.compareHkApplyOLD(app, other, inOrder)
- }
- else super.compareHkApplyOLD(app, other, inOrder)
-
- override def compareHkLambdaOLD(tp1: Type, tp2: RefinedType): Boolean =
- if (tp2.isTypeParam)
- traceIndented(i"compareHkLambda $tp1, $tp2") {
- super.compareHkLambdaOLD(tp1, tp2)
- }
- else super.compareHkLambdaOLD(tp1, tp2)
-
override def toString = "Subtype trace:" + { try b.toString finally b.clear() }
}
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index 0d02de1da..3a797cce3 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -158,7 +158,6 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
tp
case tp: RefinedType =>
tp.derivedRefinedType(simplify(tp.parent, theMap), tp.refinedName, simplify(tp.refinedInfo, theMap))
- .normalizeHkApplyOLD
case tp: TypeAlias =>
tp.derivedTypeAlias(simplify(tp.alias, theMap))
case AndType(l, r) =>
@@ -386,7 +385,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
// Strip all refinements from parent type, populating `refinements` and `formals` maps.
def normalizeToRef(tp: Type): TypeRef = {
def fail = throw new TypeError(s"unexpected parent type: $tp")
- tp.dealias.normalizeHkApplyOLD match {
+ tp.dealias match {
case tp: TypeRef =>
tp
case tp @ RefinedType(tp1, name: TypeName, rinfo) =>
diff --git a/src/dotty/tools/dotc/core/TypeParamInfo.scala b/src/dotty/tools/dotc/core/TypeParamInfo.scala
new file mode 100644
index 000000000..ff3c8fca7
--- /dev/null
+++ b/src/dotty/tools/dotc/core/TypeParamInfo.scala
@@ -0,0 +1,29 @@
+package dotty.tools.dotc.core
+
+import Names.Name
+import Contexts.Context
+import Types.{Type, TypeBounds}
+
+/** A common super trait of Symbol and LambdaParam.
+ * Used to capture the attributes of type parameters which can be implemented as either.
+ */
+trait TypeParamInfo {
+
+ /** Is this the info of a type parameter? Might be wrong for symbols */
+ def isTypeParam(implicit ctx: Context): Boolean
+
+ /** The name of the type parameter */
+ def paramName(implicit ctx: Context): Name
+
+ /** The info of the type parameter */
+ def paramBounds(implicit ctx: Context): TypeBounds
+
+ /** The info of the type parameter as seen from a prefix type.
+ * This can be different from `memberInfo` if the binding
+ * is a type symbol of a class.
+ */
+ def paramBoundsAsSeenFrom(pre: Type)(implicit ctx: Context): TypeBounds
+
+ /** The variance of the type parameter */
+ def paramVariance(implicit ctx: Context): Int
+} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index c9d2b5029..9150925ff 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -116,12 +116,8 @@ object Types {
case TypeAlias(tp) => tp.isRef(sym)
case _ => this1.symbol eq sym
}
- case this1: RefinedType =>
- !this1.isTypeParam && this1.parent.isRef(sym)
- case this1: RecType =>
- this1.parent.isRef(sym)
- case _ =>
- false
+ case this1: RefinedOrRecType => this1.parent.isRef(sym)
+ case _ => false
}
/** Is this type a (neither aliased nor applied) reference to class `sym`? */
@@ -939,7 +935,7 @@ object Types {
tp.underlying.underlyingClassRef(refinementOK)
case tp: RefinedType =>
def isParamName = tp.classSymbol.typeParams.exists(_.name == tp.refinedName)
- if (refinementOK || tp.isTypeParam || isParamName) tp.underlying.underlyingClassRef(refinementOK)
+ if (refinementOK || isParamName) tp.underlying.underlyingClassRef(refinementOK)
else NoType
case tp: RecType =>
tp.underlying.underlyingClassRef(refinementOK)
@@ -2099,8 +2095,7 @@ object Types {
* @param infoFn: A function that produces the info of the refinement declaration,
* given the refined type itself.
*/
- abstract case class RefinedType(parent: Type, refinedName: Name, refinedInfo: Type)
- extends RefinedOrRecType with BindingType with MemberBinding {
+ abstract case class RefinedType(parent: Type, refinedName: Name, refinedInfo: Type) extends RefinedOrRecType {
override def underlying(implicit ctx: Context) = parent
@@ -2111,42 +2106,6 @@ object Types {
this
}
- def betaReduceOLD(implicit ctx: Context): Type = refinedInfo match {
- case TypeAlias(alias) if refinedName.isHkArgNameOLD =>
- def instantiate(rt: RecType) = new TypeMap {
- def apply(t: Type) = t match {
- case TypeRef(RecThis(`rt`), `refinedName`) => alias
- case tp: TypeRef =>
- val pre1 = apply(tp.prefix)
- if (pre1 ne tp.prefix) tp.newLikeThis(pre1) else tp
- case _ => mapOver(t)
- }
- }
- def substAlias(tp: Type): Type = tp.safeDealias match {
- case tp @ RefinedType(p, rname, rinfo) if tp.isTypeParam =>
- if (rname == refinedName) p // check bounds?
- else tp.derivedRefinedType(substAlias(p), rname, rinfo)
- case tp: RecType =>
- val p1 = substAlias(tp.parent)
- if (p1 ne tp.parent) tp.rebind(instantiate(tp)(p1))
- else tp
- case _ =>
- tp
- }
- parent match {
- case parent: LazyRef =>
- LazyRef(() => derivedRefinedType(parent.ref, refinedName, refinedInfo))
- case _ =>
- val reduced = substAlias(parent)
- if (reduced ne parent) {
- hk.println(i"REDUCE $this ----> ${reduced}")
- reduced
- } else this
- }
- case _ =>
- this
- }
-
def derivedRefinedType(parent: Type, refinedName: Name, refinedInfo: Type)(implicit ctx: Context): Type =
if ((parent eq this.parent) && (refinedName eq this.refinedName) && (refinedInfo eq this.refinedInfo)) this
else {
@@ -2156,7 +2115,7 @@ object Types {
// A Y-check error (incompatible types involving hk lambdas) for dotty itself.
// TODO: investigate and, if possible, drop after revision.
val normalizedRefinedInfo = refinedInfo.substRecThis(dummyRec, dummyRec)
- RefinedType(parent, refinedName, normalizedRefinedInfo).betaReduceOLD
+ RefinedType(parent, refinedName, normalizedRefinedInfo)
}
/** Add this refinement to `parent`, provided If `refinedName` is a member of `parent`. */
@@ -2164,17 +2123,6 @@ object Types {
if (parent.member(refinedName).exists) derivedRefinedType(parent, refinedName, refinedInfo)
else parent
- // MemberBinding methods
- // TODO: Needed?
- def isTypeParam(implicit ctx: Context) = refinedInfo match {
- case tp: TypeBounds => tp.isBinding
- case _ => false
- }
- def memberName(implicit ctx: Context) = refinedName
- def memberBounds(implicit ctx: Context) = refinedInfo.bounds
- def memberBoundsAsSeenFrom(pre: Type)(implicit ctx: Context) = memberBounds
- def memberVariance(implicit ctx: Context) = BindingKind.toVariance(refinedInfo.bounds.bindingKind)
-
override def equals(that: Any) = that match {
case that: RefinedType =>
this.parent == that.parent &&
@@ -2623,7 +2571,7 @@ object Types {
def duplicate(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): GenericType
- def lifted(tparams: List[MemberBinding], t: Type)(implicit ctx: Context): Type =
+ def lifted(tparams: List[TypeParamInfo], t: Type)(implicit ctx: Context): Type =
tparams match {
case LambdaParam(poly, _) :: _ =>
t.subst(poly, this)
@@ -2710,12 +2658,12 @@ object Types {
}
/** The parameter of a type lambda */
- case class LambdaParam(tl: TypeLambda, n: Int) extends MemberBinding {
+ case class LambdaParam(tl: TypeLambda, n: Int) extends TypeParamInfo {
def isTypeParam(implicit ctx: Context) = true
- def memberName(implicit ctx: Context): TypeName = tl.paramNames(n)
- def memberBounds(implicit ctx: Context): TypeBounds = tl.paramBounds(n)
- def memberBoundsAsSeenFrom(pre: Type)(implicit ctx: Context): TypeBounds = memberBounds
- def memberVariance(implicit ctx: Context): Int = tl.variances(n)
+ def paramName(implicit ctx: Context): TypeName = tl.paramNames(n)
+ def paramBounds(implicit ctx: Context): TypeBounds = tl.paramBounds(n)
+ def paramBoundsAsSeenFrom(pre: Type)(implicit ctx: Context): TypeBounds = paramBounds
+ def paramVariance(implicit ctx: Context): Int = tl.variances(n)
def toArg: Type = PolyParam(tl, n)
}
@@ -2756,7 +2704,7 @@ object Types {
case _ => defn.AnyType
}
- def typeParams(implicit ctx: Context): List[MemberBinding] = {
+ def typeParams(implicit ctx: Context): List[TypeParamInfo] = {
val tparams = tycon.typeParams
if (tparams.isEmpty) TypeLambda.any(args.length).typeParams else tparams
}
@@ -3574,10 +3522,10 @@ object Types {
if (inst.exists) apply(inst) else tp
case tp: HKApply =>
- def mapArg(arg: Type, tparam: MemberBinding): Type = {
+ def mapArg(arg: Type, tparam: TypeParamInfo): Type = {
val saved = variance
- if (tparam.memberVariance < 0) variance = -variance
- else if (tparam.memberVariance == 0) variance = 0
+ if (tparam.paramVariance < 0) variance = -variance
+ else if (tparam.paramVariance == 0) variance = 0
try this(arg)
finally variance = saved
}
diff --git a/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/src/dotty/tools/dotc/core/tasty/TreePickler.scala
index f604bff62..6a51b9642 100644
--- a/src/dotty/tools/dotc/core/tasty/TreePickler.scala
+++ b/src/dotty/tools/dotc/core/tasty/TreePickler.scala
@@ -257,7 +257,7 @@ class TreePickler(pickler: TastyPickler) {
case tpe: TypeLambda =>
writeByte(LAMBDAtype)
val paramNames = tpe.typeParams.map(tparam =>
- varianceToPrefix(tparam.memberVariance) +: tparam.memberName)
+ varianceToPrefix(tparam.paramVariance) +: tparam.paramName)
pickleMethodic(tpe.resultType, paramNames, tpe.paramBounds)
case tpe: MethodType if richTypes =>
writeByte(METHODtype)
diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala
index 880804b9e..656650d91 100644
--- a/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -51,8 +51,6 @@ class PlainPrinter(_ctx: Context) extends Printer {
homogenize(tp1) & homogenize(tp2)
case OrType(tp1, tp2) =>
homogenize(tp1) | homogenize(tp2)
- case tp: RefinedType if !Config.newHK =>
- tp.normalizeHkApplyOLD
case tp: SkolemType =>
homogenize(tp.info)
case tp: LazyRef =>
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index c772267e7..34456d0b9 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -113,36 +113,6 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
if (defn.isFunctionClass(cls)) return toTextFunction(args)
if (defn.isTupleClass(cls)) return toTextTuple(args)
return (toTextLocal(tycon) ~ "[" ~ Text(args map argText, ", ") ~ "]").close
- case tp @ TypeLambdaOLD(argBoundss, body) =>
- val variances = argBoundss.map(b => BindingKind.toVariance(b.bindingKind))
- val prefix = ((('X' - 'A') + lambdaNestingLevel) % 26 + 'A').toChar
- val paramNames = argBoundss.indices.toList.map(prefix.toString + _)
- val instantiate = new TypeMap {
- def contains(tp1: Type, tp2: Type): Boolean =
- tp1.eq(tp2) || {
- tp1.stripTypeVar match {
- case tp1: RefinedOrRecType => contains(tp1.parent, tp2)
- case _ => false
- }
- }
- def apply(t: Type): Type = t match {
- case TypeRef(RecThis(rt), name) if name.isHkArgNameOLD && contains(tp, rt) =>
- // Make up a name that prints as "Xi". Need to be careful we do not
- // accidentally unique-hash to something else. That's why we can't
- // use prefix = NoPrefix or a WithFixedSym instance.
- TypeRef.withSymAndName(
- defn.EmptyPackageClass.thisType, defn.AnyClass,
- paramNames(name.hkArgIndexOLD).toTypeName)
- case _ =>
- mapOver(t)
- }
- }
- val instArgs = argBoundss.map(instantiate).asInstanceOf[List[TypeBounds]]
- val instBody = instantiate(body).dropAlias
- lambdaNestingLevel += 1
- try
- return typeLambdaText(paramNames, variances, instArgs, instBody)
- finally lambdaNestingLevel -=1
case tp: TypeRef =>
val hideType = tp.symbol is AliasPreferred
if (hideType && !ctx.phase.erasedTypes && !tp.symbol.isCompleting) {
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala
index e26ea1138..0344ae6c6 100644
--- a/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -4,10 +4,9 @@ package typer
import core._
import ast._
-import config.Config.newHK
import Scopes._, Contexts._, Constants._, Types._, Symbols._, Names._, Flags._, Decorators._
import ErrorReporting._, Annotations._, Denotations._, SymDenotations._, StdNames._, TypeErasure._
-import TypeApplications.{AppliedType, TypeLambdaOLD}
+import TypeApplications.AppliedType
import util.Positions._
import config.Printers._
import ast.Trees._
@@ -99,7 +98,7 @@ trait TypeAssigner {
val base = apply(tycon)
var args = tp.baseArgInfos(base.typeSymbol)
if (base.typeParams.length != args.length)
- args = base.typeParams.map(_.memberBounds)
+ args = base.typeParams.map(_.paramBounds)
base.appliedTo(args)
case tp @ RefinedType(parent, name, rinfo) if variance > 0 =>
val parent1 = apply(tp.parent)
@@ -413,7 +412,7 @@ trait TypeAssigner {
def refineNamed(tycon: Type, arg: Tree) = arg match {
case ast.Trees.NamedArg(name, argtpt) =>
// Dotty deviation: importing ast.Trees._ and matching on NamedArg gives a cyclic ref error
- val tparam = tparams.find(_.memberName == name) match {
+ val tparam = tparams.find(_.paramName == name) match {
case Some(tparam) => tparam
case none => ntparams.find(_.name == name).getOrElse(NoSymbol)
}
@@ -430,16 +429,7 @@ trait TypeAssigner {
}
def assignType(tree: untpd.TypeLambdaTree, tparamDefs: List[TypeDef], body: Tree)(implicit ctx: Context) =
- if (newHK) tree.withType(TypeLambda.fromSymbols(tparamDefs.map(_.symbol), body.tpe))
- else {
- val tparams = tparamDefs.map(_.symbol)
- val argBindingFns = tparams.map(tparam =>
- tparam.info.bounds
- .withBindingKind(BindingKind.fromVariance(tparam.variance))
- .recursifyOLD(tparams))
- val bodyFn = body.tpe.recursifyOLD(tparams)
- tree.withType(TypeLambdaOLD(argBindingFns, bodyFn))
- }
+ tree.withType(TypeLambda.fromSymbols(tparamDefs.map(_.symbol), body.tpe))
def assignType(tree: untpd.ByNameTypeTree, result: Tree)(implicit ctx: Context) =
tree.withType(ExprType(result.tpe))
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 49d69f04e..da176427a 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -942,10 +942,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
ctx.error(d"wrong number of type arguments for ${tpt1.tpe}, should be ${tparams.length}", tree.pos)
args = args.take(tparams.length)
}
- def typedArg(arg: untpd.Tree, tparam: MemberBinding) = {
+ def typedArg(arg: untpd.Tree, tparam: TypeParamInfo) = {
val (desugaredArg, argPt) =
if (ctx.mode is Mode.Pattern)
- (if (isVarPattern(arg)) desugar.patternVar(arg) else arg, tparam.memberBounds)
+ (if (isVarPattern(arg)) desugar.patternVar(arg) else arg, tparam.paramBounds)
else
(arg, WildcardType)
typed(desugaredArg, argPt)
diff --git a/src/dotty/tools/dotc/typer/Variances.scala b/src/dotty/tools/dotc/typer/Variances.scala
index a2f9a0f16..a8abe5e30 100644
--- a/src/dotty/tools/dotc/typer/Variances.scala
+++ b/src/dotty/tools/dotc/typer/Variances.scala
@@ -84,11 +84,11 @@ object Variances {
case ExprType(restpe) =>
varianceInType(restpe)(tparam)
case tp @ HKApply(tycon, args) =>
- def varianceInArgs(v: Variance, args: List[Type], tparams: List[MemberBinding]): Variance =
+ def varianceInArgs(v: Variance, args: List[Type], tparams: List[TypeParamInfo]): Variance =
args match {
case arg :: args1 =>
varianceInArgs(
- v & compose(varianceInType(arg)(tparam), tparams.head.memberVariance),
+ v & compose(varianceInType(arg)(tparam), tparams.head.paramVariance),
args1, tparams.tail)
case nil =>
v