aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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