aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/config/Config.scala2
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala65
-rw-r--r--src/dotty/tools/dotc/core/NameOps.scala8
-rw-r--r--src/dotty/tools/dotc/core/StdNames.scala6
-rw-r--r--src/dotty/tools/dotc/core/Substituters.scala22
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala4
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala307
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala143
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala155
-rw-r--r--src/dotty/tools/dotc/core/Uniques.scala4
-rw-r--r--src/dotty/tools/dotc/core/tasty/TastyFormat.scala3
-rw-r--r--src/dotty/tools/dotc/core/tasty/TreePickler.scala5
-rw-r--r--src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala11
-rw-r--r--src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala2
-rw-r--r--src/dotty/tools/dotc/printing/PlainPrinter.scala5
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala4
-rw-r--r--src/dotty/tools/dotc/sbt/ExtractAPI.scala4
-rw-r--r--src/dotty/tools/dotc/sbt/ExtractDependencies.scala3
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala4
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala5
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala25
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala3
23 files changed, 104 insertions, 688 deletions
diff --git a/src/dotty/tools/dotc/config/Config.scala b/src/dotty/tools/dotc/config/Config.scala
index 1c22329f1..7dfc09b3f 100644
--- a/src/dotty/tools/dotc/config/Config.scala
+++ b/src/dotty/tools/dotc/config/Config.scala
@@ -8,8 +8,6 @@ object Config {
final val cacheMemberNames = true
final val cacheImplicitScopes = true
- final val newHK = true
-
final val checkCacheMembersNamed = false
/** When updating a constraint bound, check that the constrained parameter
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index 44d36abc5..5db9a6b0d 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -663,71 +663,6 @@ class Definitions {
def functionArity(tp: Type)(implicit ctx: Context) = tp.dealias.argInfos.length - 1
- // ----- LambdaXYZ traits ------------------------------------------
-
- private var myLambdaTraits: Set[Symbol] = Set()
-
- /** The set of HigherKindedXYZ traits encountered so far */
- def lambdaTraitsOBS: Set[Symbol] = myLambdaTraits
-
- private var LambdaTraitForVariances = mutable.Map[List[Int], ClassSymbol]()
-
- /** The HigherKinded trait corresponding to symbols `boundSyms` (which are assumed
- * to be the type parameters of a higher-kided type). This is a class symbol that
- * would be generated by the following schema.
- *
- * trait LambdaXYZ extends Object with P1 with ... with Pn {
- * type v_1 hk$0; ...; type v_N hk$N;
- * type +$Apply
- * }
- *
- * Here:
- *
- * - v_i are the variances of the bound symbols (i.e. +, -, or empty).
- * - XYZ is a string of length N with one letter for each variant of a bound symbol,
- * using `P` (positive variance), `N` (negative variance), `I` (invariant).
- * - for each positive or negative variance v_i there is a parent trait Pj which
- * is the same as LambdaXYZ except that it has `I` in i-th position.
- */
- def LambdaTraitOBS(vcs: List[Int]): ClassSymbol = {
- assert(vcs.nonEmpty)
-
- def varianceFlags(v: Int) = v match {
- case -1 => Contravariant
- case 0 => EmptyFlags
- case 1 => Covariant
- }
-
- val completer = new LazyType {
- def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
- val cls = denot.asClass.classSymbol
- val paramDecls = newScope
- for (i <- 0 until vcs.length)
- newTypeParam(cls, tpnme.hkArg(i), varianceFlags(vcs(i)), paramDecls)
- newTypeField(cls, tpnme.hkApplyOBS, Covariant, paramDecls)
- val parentTraitRefs =
- for (i <- 0 until vcs.length if vcs(i) != 0)
- yield LambdaTraitOBS(vcs.updated(i, 0)).typeRef
- denot.info = ClassInfo(
- ScalaPackageClass.thisType, cls, ObjectClass.typeRef :: parentTraitRefs.toList, paramDecls)
- }
- }
-
- val traitName = tpnme.hkLambdaOBS(vcs)
-
- def createTrait = {
- val cls = newClassSymbol(
- ScalaPackageClass,
- traitName,
- PureInterfaceCreationFlags | Synthetic,
- completer)
- myLambdaTraits += cls
- cls
- }
-
- LambdaTraitForVariances.getOrElseUpdate(vcs, createTrait)
- }
-
// ----- primitive value class machinery ------------------------------------------
/** This class would also be obviated by the implicit function type design */
diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala
index 1f221b5c8..b5704480a 100644
--- a/src/dotty/tools/dotc/core/NameOps.scala
+++ b/src/dotty/tools/dotc/core/NameOps.scala
@@ -116,14 +116,6 @@ object NameOps {
def hkArgIndex: Int =
name.drop(tpnme.hkArgPrefixLength).toString.toInt
- def isLambdaTraitNameOBS(implicit ctx: Context): Boolean =
- name.isTypeName && name.startsWith(tpnme.hkLambdaPrefixOBS)
-
- def lambdaTraitVariancesOBS(implicit ctx: Context): List[Int] = {
- val vs = name.drop(tpnme.hkLambdaPrefixOBS.length)
- vs.toList.map(c => tpnme.varianceSuffixesOBS.indexOf(c) - 1)
- }
-
/** 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 e82260201..c767f4c29 100644
--- a/src/dotty/tools/dotc/core/StdNames.scala
+++ b/src/dotty/tools/dotc/core/StdNames.scala
@@ -529,9 +529,7 @@ object StdNames {
val synthSwitch: N = "$synthSwitch"
- val hkApplyOBS: N = "$Apply"
val hkArgPrefix: N = "$hk"
- val hkLambdaPrefixOBS: N = "Lambda$"
val hkArgPrefixHead: Char = hkArgPrefix.head
val hkArgPrefixLength: Int = hkArgPrefix.length
@@ -744,12 +742,8 @@ object StdNames {
def syntheticTypeParamNames(num: Int): List[TypeName] =
(0 until num).map(syntheticTypeParamName)(breakOut)
- def hkLambdaOBS(vcs: List[Int]): TypeName = hkLambdaPrefixOBS ++ vcs.map(varianceSuffixOBS).mkString
def hkArg(n: Int): TypeName = hkArgPrefix ++ n.toString
- def varianceSuffixOBS(v: Int): Char = varianceSuffixesOBS.charAt(v + 1)
- val varianceSuffixesOBS = "NIP"
-
final val Conforms = encode("<:<")
}
diff --git a/src/dotty/tools/dotc/core/Substituters.scala b/src/dotty/tools/dotc/core/Substituters.scala
index 4598aaa20..0d1c78e2f 100644
--- a/src/dotty/tools/dotc/core/Substituters.scala
+++ b/src/dotty/tools/dotc/core/Substituters.scala
@@ -179,24 +179,6 @@ trait Substituters { this: Context =>
.mapOver(tp)
}
- final def substRefinedThis(tp: Type, from: Type, to: Type, theMap: SubstRefinedThisMap): Type =
- tp match {
- case tp @ RefinedThis(binder) =>
- if (binder eq from) to else tp
- case tp: NamedType =>
- if (tp.currentSymbol.isStatic) tp
- else tp.derivedSelect(substRefinedThis(tp.prefix, from, to, theMap))
- case _: ThisType | _: BoundType | NoPrefix =>
- tp
- case tp: RefinedType =>
- tp.derivedRefinedType(substRefinedThis(tp.parent, from, to, theMap), tp.refinedName, substRefinedThis(tp.refinedInfo, from, to, theMap))
- case tp: TypeAlias =>
- tp.derivedTypeAlias(substRefinedThis(tp.alias, from, to, theMap))
- case _ =>
- (if (theMap != null) theMap else new SubstRefinedThisMap(from, to))
- .mapOver(tp)
- }
-
final def substRecThis(tp: Type, from: Type, to: Type, theMap: SubstRecThisMap): Type =
tp match {
case tp @ RecThis(binder) =>
@@ -284,10 +266,6 @@ trait Substituters { this: Context =>
def apply(tp: Type): Type = substThis(tp, from, to, this)
}
- final class SubstRefinedThisMap(from: Type, to: Type) extends DeepTypeMap {
- def apply(tp: Type): Type = substRefinedThis(tp, from, to, this)
- }
-
final class SubstRecThisMap(from: Type, to: Type) extends DeepTypeMap {
def apply(tp: Type): Type = substRecThis(tp, from, to, this)
}
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 124199678..e8053a740 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -483,10 +483,6 @@ object SymDenotations {
final def isRefinementClass(implicit ctx: Context): Boolean =
name.decode == tpnme.REFINE_CLASS
- /** is this symbol a trait representing a type lambda? */
- final def isLambdaTraitOBS(implicit ctx: Context): Boolean =
- isClass && name.startsWith(tpnme.hkLambdaPrefixOBS) && owner == defn.ScalaPackageClass
-
/** Is this symbol a package object or its module class? */
def isPackageObject(implicit ctx: Context): Boolean = {
val poName = if (isType) nme.PACKAGE_CLS else nme.PACKAGE
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index 0edc598dd..33aa060b5 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -81,7 +81,6 @@ object TypeApplications {
object TypeLambda {
def apply(argBindingFns: List[RecType => TypeBounds],
bodyFn: RecType => Type)(implicit ctx: Context): Type = {
- assert(Config.newHK)
val argNames = argBindingFns.indices.toList.map(tpnme.hkArg)
var idx = 0
RecType.closeOver(rt =>
@@ -92,54 +91,19 @@ object TypeApplications {
})
}
- def applyOBS(variances: List[Int],
- argBoundsFns: List[RefinedType => TypeBounds],
- bodyFn: RefinedType => Type)(implicit ctx: Context): Type = {
- def argRefinements(parent: Type, i: Int, bs: List[RefinedType => TypeBounds]): Type = bs match {
- case b :: bs1 =>
- argRefinements(RefinedType(parent, tpnme.hkArg(i), b), i + 1, bs1)
- case nil =>
- parent
+ 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)
}
- assert(variances.nonEmpty)
- assert(argBoundsFns.length == variances.length)
- RefinedType(
- argRefinements(defn.LambdaTraitOBS(variances).typeRef, 0, argBoundsFns),
- tpnme.hkApplyOBS, bodyFn(_).bounds.withVariance(1))
- }
-
- def unapply(tp: Type)(implicit ctx: Context): Option[(/*List[Int], */List[TypeBounds], Type)] =
- if (Config.newHK) {
- 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)
-// case (bindings, tp) => Some((Nil, bindings, tp))
- }
+ decompose(tp, Nil) match {
+ case (Nil, _) => None
+ case x => Some(x)
}
- else tp match {
- case app @ RefinedType(parent, tpnme.hkApplyOBS, refinedInfo) =>
- val cls = parent.typeSymbol
- val variances = cls.typeParams.map(_.variance)
- def collectBounds(t: Type, acc: List[TypeBounds]): List[TypeBounds] = t match {
- case t @ RefinedType(p, rname, rinfo) =>
- assert(rname.isHkArgName)
- collectBounds(p, rinfo.bounds :: acc)
- case TypeRef(_, lname) =>
- assert(lname.isLambdaTraitNameOBS)
- acc
- }
- val argBounds = collectBounds(parent, Nil)
- Some((argBounds, refinedInfo.argInfo))
- case _ =>
- None
}
}
@@ -162,7 +126,7 @@ object TypeApplications {
def argsAreForwarders(args: List[Type], n: Int): Boolean = args match {
case Nil =>
n == 0
- case TypeRef(RefinedThis(rt), sel) :: args1 =>
+ case TypeRef(RecThis(rt), sel) :: args1 if false =>
rt.eq(tp) && sel == tpnme.hkArg(n - 1) && argsAreForwarders(args1, n - 1)
case _ =>
false
@@ -179,17 +143,13 @@ object TypeApplications {
*
* T { type p_1 v_1= U_1; ...; type p_n v_n= U_n }
*
- * where v_i, p_i are the variances and names of the type parameters of T,
- * If `T`'s class symbol is a lambda trait, follow the refined type with a
- * projection
- *
- * T { ... } # $Apply
+ * where v_i, p_i are the variances and names of the type parameters of T.
*/
object AppliedType {
def apply(tp: Type, args: List[Type])(implicit ctx: Context): Type = tp.appliedTo(args)
def unapply(tp: Type)(implicit ctx: Context): Option[(Type, List[Type])] = tp match {
- case tp: RefinedType if Config.newHK =>
+ case tp: RefinedType =>
var refinements: List[RefinedType] = Nil
var tycon = tp.stripTypeVar
while (tycon.isInstanceOf[RefinedType]) {
@@ -209,38 +169,8 @@ object TypeApplications {
None
}
collectArgs(tycon.typeParams, refinements, new mutable.ListBuffer[Type])
- case TypeRef(prefix, tpnme.hkApplyOBS) if !Config.newHK =>
- unapp(prefix)
case _ =>
- if (Config.newHK) None
- else unapp(tp) match {
- case Some((tycon: TypeRef, _)) if tycon.symbol.isLambdaTraitOBS =>
- // We are seeing part of a lambda abstraction, not an applied type
- None
- case x => x
- }
- }
-
- private def unapp(tp: Type)(implicit ctx: Context): Option[(Type, List[Type])] = tp match {
- case _: RefinedType =>
- val tparams = tp.classSymbol.typeParams
- if (tparams.isEmpty) None
- else {
- val argBuf = new mutable.ListBuffer[Type]
- def stripArgs(tp: Type, n: Int): Type =
- if (n == 0) tp
- else tp match {
- case tp @ RefinedType(parent, pname, rinfo) if pname == tparams(n - 1).name =>
- val res = stripArgs(parent, n - 1)
- if (res.exists) argBuf += rinfo.argInfo
- res
- case _ =>
- NoType
- }
- val res = stripArgs(tp, tparams.length)
- if (res.exists) Some((res, argBuf.toList)) else None
- }
- case _ => None
+ None
}
}
@@ -257,50 +187,9 @@ object TypeApplications {
}
/** The references `<rt>.this.$hk0, ..., <rt>.this.$hk<n-1>`. */
- def argRefs(rt: RefinedType, n: Int)(implicit ctx: Context) =
- List.range(0, n).map(i => RefinedThis(rt).select(tpnme.hkArg(i)))
-
- /** The references `<rt>.this.$hk0, ..., <rt>.this.$hk<n-1>`. */
def argRefs(rt: RecType, n: Int)(implicit ctx: Context) =
List.range(0, n).map(i => RecThis(rt).select(tpnme.hkArg(i)))
- /** Merge `tp1` and `tp2` under a common lambda, combining them with `op`.
- * @param tparams1 The type parameters of `tp1`
- * @param tparams2 The type parameters of `tp2`
- * @pre tparams1.length == tparams2.length
- * Produces the type lambda
- *
- * [v1 X1 B1, ..., vn Xn Bn] -> op(tp1[X1, ..., Xn], tp2[X1, ..., Xn])
- *
- * where
- *
- * - variances `vi` are the variances of corresponding type parameters for `tp1`
- * or `tp2`, or are 0 of the latter disagree.
- * - bounds `Bi` are the intersection of the corresponding type parameter bounds
- * of `tp1` and `tp2`.
- */
- def hkCombineOBS(tp1: Type, tp2: Type,
- tparams1: List[TypeSymbol], tparams2: List[TypeSymbol], op: (Type, Type) => Type)
- (implicit ctx: Context): Type = {
- val variances = (tparams1, tparams2).zipped.map { (tparam1, tparam2) =>
- val v1 = tparam1.variance
- val v2 = tparam2.variance
- if (v1 == v2) v1 else 0
- }
- val bounds: List[RefinedType => TypeBounds] =
- (tparams1, tparams2).zipped.map { (tparam1, tparam2) =>
- val b1: RefinedType => TypeBounds =
- tp1.memberInfo(tparam1).bounds.internalizeFrom(tparams1)
- val b2: RefinedType => TypeBounds =
- tp2.memberInfo(tparam2).bounds.internalizeFrom(tparams2)
- (rt: RefinedType) => b1(rt) & b2(rt)
- }
- val app1: RefinedType => Type = rt => tp1.appliedTo(argRefs(rt, tparams1.length))
- val app2: RefinedType => Type = rt => tp2.appliedTo(argRefs(rt, tparams2.length))
- val body: RefinedType => Type = rt => op(app1(rt), app2(rt))
- TypeLambda.applyOBS(variances, bounds, body)
- }
-
private class InstMap(fullType: Type)(implicit ctx: Context) extends TypeMap {
var localRecs: Set[RecType] = Set.empty
var keptRefs: Set[Name] = Set.empty
@@ -349,33 +238,10 @@ class TypeApplications(val self: Type) extends AnyVal {
self.cls.typeParams
case self: TypeRef =>
val tsym = self.symbol
- if (tsym.isClass) tsym.typeParams
- else tsym.infoOrCompleter match {
- case completer: TypeParamsCompleter =>
- val tparams = completer.completerTypeParams(tsym)
- if (Config.newHK) fallbackTypeParams(tparams.map(_.variance))
- else defn.LambdaTraitOBS(tparams.map(_.variance)).typeParams
- case _ =>
- if (!tsym.isCompleting || tsym.isAliasType) tsym.info.typeParams
- else
- // We are facing a problem when computing the type parameters of an uncompleted
- // abstract type. We can't access the bounds of the symbol yet because that
- // would cause a cause a cyclic reference. So we return `Nil` instead
- // and try to make up for it later. The acrobatics in Scala2Unpicker#readType
- // for reading a TypeRef show what's needed.
- Nil
- }
+ if (tsym.isClass) tsym.typeParams else tsym.info.typeParams
case self: RefinedType =>
- // inlined and optimized version of
- // val sym = self.LambdaTrait
- // if (sym.exists) return sym.typeParams
- if (!Config.newHK && self.refinedName == tpnme.hkApplyOBS) {
- val sym = self.parent.classSymbol
- if (sym.isLambdaTraitOBS) return sym.typeParams
- }
val precedingParams = self.parent.typeParams.filterNot(_.memberName == self.refinedName)
- if (Config.newHK && self.isTypeParam) precedingParams :+ self
- else precedingParams
+ if (self.isTypeParam) precedingParams :+ self else precedingParams
case self: RecType =>
self.parent.typeParams
case self: SingletonType =>
@@ -389,9 +255,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] =
- if (Config.newHK)
- if (isHK) typeParams else Nil
- else LambdaTraitOBS.typeParams
+ if (isHK) typeParams else Nil
/** If `self` is a generic class, its type parameter symbols, otherwise Nil */
final def typeParamSymbols(implicit ctx: Context): List[TypeSymbol] = typeParams match {
@@ -462,19 +326,10 @@ class TypeApplications(val self: Type) extends AnyVal {
}
}
- /** The Lambda trait underlying a type lambda */
- def LambdaTraitOBS(implicit ctx: Context): Symbol = self.stripTypeVar match {
- case RefinedType(_, tpnme.hkApplyOBS, _) =>
- val sym = self.classSymbol
- if (sym.isLambdaTraitOBS) sym else NoSymbol
- case TypeBounds(lo, hi) => hi.LambdaTraitOBS
- case _ => NoSymbol
- }
-
/** 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 => self.refinedName == tpnme.hkApplyOBS || self.isTypeParam
+ case self: RefinedType => self.isTypeParam
case self: SingletonType => false
case self: TypeVar => self.origin.isHK
case self: WildcardType => self.optBounds.isHK
@@ -511,8 +366,7 @@ class TypeApplications(val self: Type) extends AnyVal {
/** is receiver of the form T#$Apply? */
def isHKApply(implicit ctx: Context): Boolean = self match {
- case self @ RefinedType(_, name, _) => Config.newHK && name.isHkArgName && !self.isTypeParam
- case TypeRef(_, name) => !Config.newHK && (name == tpnme.hkApplyOBS)
+ case self @ RefinedType(_, name, _) => name.isHkArgName && !self.isTypeParam
case _ => false
}
@@ -520,18 +374,18 @@ class TypeApplications(val self: Type) extends AnyVal {
* of this application exists and is not a lambda trait.
* Equivalent to
*
- * self.classSymbol.exists && !self.classSymbol.isLambdaTrait
+ * self.classSymbol.exists
*
* but without forcing anything.
*/
- def classNotLambda(implicit ctx: Context): Boolean = self.stripTypeVar match {
+ def safeIsClassRef(implicit ctx: Context): Boolean = self.stripTypeVar match {
case self: RefinedOrRecType =>
- self.parent.classNotLambda
+ self.parent.safeIsClassRef
case self: TypeRef =>
self.denot.exists && {
val sym = self.symbol
- if (sym.isClass) !sym.isLambdaTraitOBS
- else sym.isCompleted && self.info.isAlias && self.info.bounds.hi.classNotLambda
+ sym.isClass ||
+ sym.isCompleted && self.info.isAlias
}
case _ =>
false
@@ -545,22 +399,6 @@ class TypeApplications(val self: Type) extends AnyVal {
self
}
- /** Dealias type if it can be done without forcing anything */
- def saferDealias(implicit ctx: Context): Type = self match {
- case self: TypeRef if self.denot.exists && self.symbol.isAliasType && self.symbol.isCompleted =>
- self.info.bounds.hi.stripTypeVar.safeDealias
- case _ =>
- 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 internalizeFrom[T <: Type](tparams: List[Symbol])(implicit ctx: Context): RefinedType => T =
- (rt: RefinedType) =>
- new ctx.SafeSubstMap(tparams, argRefs(rt, tparams.length))
- .apply(self).asInstanceOf[T]
-
/** Replace references to type parameters with references to hk arguments `this.$hk_i`
* Care is needed not to cause cyclic reference errors, hence `SafeSubstMap`.
*/
@@ -571,7 +409,6 @@ class TypeApplications(val self: Type) extends AnyVal {
new ctx.SafeSubstMap(tparams.asInstanceOf[List[Symbol]], argRefs(rt, tparams.length))
.apply(self).asInstanceOf[T]
case _ =>
- assert(Config.newHK)
def mapRefs(rt: RecType) = new TypeMap {
def apply(t: Type): Type = t match {
case rthis: RecThis if tparams contains rthis.binder.parent => RecThis(rt)
@@ -587,38 +424,20 @@ class TypeApplications(val self: Type) extends AnyVal {
* type T[X] >: L <: U becomes type T >: L <: ([X] -> _ <: U)
*/
def LambdaAbstract(tparams: List[Symbol])(implicit ctx: Context): Type = {
-
- /** Replace references to type parameters with references to hk arguments `this.$hk_i`
- * Care is needed not to cause cycles, hence `SafeSubstMap`.
- */
- def internalize[T <: Type](tp: T) =
- (rt: RefinedType) =>
- new ctx.SafeSubstMap(tparams, argRefs(rt, tparams.length))
- .apply(tp).asInstanceOf[T]
-
def expand(tp: Type) =
- if (Config.newHK)
- TypeLambda(
- tparams.map(tparam =>
- tparam.memberBoundsAsSeenFrom(self)
- .withBindingKind(BindingKind.fromVariance(tparam.variance))
- .recursify(tparams)),
- tp.recursify(tparams))
- else
- TypeLambda.applyOBS(
- tparams.map(_.variance),
- tparams.map(tparam => internalize(self.memberInfo(tparam).bounds)),
- internalize(tp))
+ TypeLambda(
+ tparams.map(tparam =>
+ tparam.memberBoundsAsSeenFrom(self)
+ .withBindingKind(BindingKind.fromVariance(tparam.variance))
+ .recursify(tparams)),
+ tp.recursify(tparams))
assert(!isHK, self)
self match {
case self: TypeAlias =>
self.derivedTypeAlias(expand(self.alias.normalizeHkApply))
case self @ TypeBounds(lo, hi) =>
- if (Config.newHK)
- self.derivedTypeBounds(lo, expand(hi.normalizeHkApply))
- else
- self.derivedTypeBounds(lo, expand(TypeBounds.upper(hi.normalizeHkApply)))
+ self.derivedTypeBounds(lo, expand(hi.normalizeHkApply))
case _ => expand(self)
}
}
@@ -652,7 +471,7 @@ class TypeApplications(val self: Type) extends AnyVal {
* - going from a wildcard type to its upper bound
*/
def normalizeHkApply(implicit ctx: Context): Type = self.strictDealias match {
- case self1 @ RefinedType(_, rname, _) if Config.newHK && rname.isHkArgName && self1.typeParams.isEmpty =>
+ case self1 @ RefinedType(_, rname, _) if rname.isHkArgName && self1.typeParams.isEmpty =>
val inst = new InstMap(self)
def instTop(tp: Type): Type = tp.strictDealias match {
@@ -709,7 +528,7 @@ class TypeApplications(val self: Type) extends AnyVal {
* to eta expand them.
*/
def isEtaExpandable(implicit ctx: Context) = self match {
- case self: TypeRef => self.symbol.isClass && !self.name.isLambdaTraitNameOBS
+ case self: TypeRef => self.symbol.isClass
case _ => false
}
@@ -782,7 +601,7 @@ class TypeApplications(val self: Type) extends AnyVal {
def adaptHkVariances(bound: Type)(implicit ctx: Context): Type = {
val hkParams = bound.hkTypeParams
if (hkParams.isEmpty) self
- else if (Config.newHK) {
+ else {
def adaptArg(arg: Type): Type = arg match {
case arg @ TypeLambda(tparamBounds, body) if
!arg.typeParams.corresponds(hkParams)(_.memberVariance == _.memberVariance) &&
@@ -804,25 +623,6 @@ class TypeApplications(val self: Type) extends AnyVal {
}
adaptArg(self)
}
- else {
- def adaptArg(arg: Type): Type = arg match {
- case arg: TypeRef if arg.symbol.isLambdaTraitOBS &&
- !arg.symbol.typeParams.corresponds(hkParams)(_.variance == _.memberVariance) &&
- arg.symbol.typeParams.corresponds(hkParams)(varianceConforms) =>
- arg.prefix.select(bound.LambdaTraitOBS)
- case arg: RefinedType =>
- arg.derivedRefinedType(adaptArg(arg.parent), arg.refinedName, arg.refinedInfo)
- case arg: RecType =>
- arg.derivedRecType(adaptArg(arg.parent))
- case arg @ TypeAlias(alias) =>
- arg.derivedTypeAlias(adaptArg(alias))
- case arg @ TypeBounds(lo, hi) =>
- arg.derivedTypeBounds(lo, adaptArg(hi))
- case _ =>
- arg
- }
- adaptArg(self)
- }
}
/** Encode
@@ -843,8 +643,6 @@ class TypeApplications(val self: Type) extends AnyVal {
final def appliedTo(args: List[Type])(implicit ctx: Context): Type = /*>|>*/ track("appliedTo") /*<|<*/ {
def substHkArgs = new TypeMap {
def apply(tp: Type): Type = tp match {
- case TypeRef(RefinedThis(rt), name) if rt.eq(self) && name.isHkArgName =>
- args(name.hkArgIndex)
case TypeRef(RecThis(rt), name) if rt.eq(self) && name.isHkArgName =>
args(name.hkArgIndex)
case _ =>
@@ -886,8 +684,7 @@ class TypeApplications(val self: Type) extends AnyVal {
assert(args.nonEmpty)
matchParams(self, typParams, args) match {
case refined @ RefinedType(_, pname, _) if pname.isHkArgName =>
- if (Config.newHK) refined.betaReduce
- else TypeRef(refined, tpnme.hkApplyOBS)
+ refined.betaReduce // TODO Move to matchparams
case refined =>
refined
}
@@ -906,8 +703,7 @@ class TypeApplications(val self: Type) extends AnyVal {
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")
- if (Config.newHK) fallbackTypeParams(args map alwaysZero)
- else defn.LambdaTraitOBS(args map alwaysZero).typeParams
+ fallbackTypeParams(args map alwaysZero)
case _ =>
typeParams
}
@@ -1070,33 +866,4 @@ class TypeApplications(val self: Type) extends AnyVal {
case JavaArrayType(elemtp) => elemtp
case _ => firstBaseArgInfo(defn.SeqClass)
}
-
- /** Does this type contain RefinedThis type with `target` as its underling
- * refinement type?
- */
- def containsRefinedThis(target: Type)(implicit ctx: Context): Boolean = {
- def recur(tp: Type): Boolean = tp.stripTypeVar match {
- case RefinedThis(tp) =>
- tp eq target
- case tp: NamedType =>
- if (tp.symbol.isClass) !tp.symbol.isStatic && recur(tp.prefix)
- else tp.info match {
- case TypeAlias(alias) => recur(alias)
- case _ => recur(tp.prefix)
- }
- case tp: RefinedType =>
- recur(tp.refinedInfo) || recur(tp.parent)
- case tp: RecType =>
- recur(tp.parent)
- case tp: TypeBounds =>
- recur(tp.lo) || recur(tp.hi)
- case tp: AnnotatedType =>
- recur(tp.underlying)
- case tp: AndOrType =>
- recur(tp.tp1) || recur(tp.tp2)
- case _ =>
- false
- }
- !Config.newHK && recur(self)
- }
}
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index c1b275b70..cf3086323 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -178,11 +178,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
&& !tp1.isInstanceOf[WithFixedSym]
&& !tp2.isInstanceOf[WithFixedSym]
) ||
- compareHkApplyOBS(tp1, tp2, inOrder = true) ||
- compareHkApplyOBS(tp2, tp1, inOrder = false) ||
thirdTryNamed(tp1, tp2)
case _ =>
- compareHkApplyOBS(tp2, tp1, inOrder = false) ||
secondTry(tp1, tp2)
}
}
@@ -259,7 +256,6 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
if (tp1.prefix.isStable) return false
case _ =>
}
- compareHkApplyOBS(tp1, tp2, inOrder = true) ||
thirdTry(tp1, tp2)
case tp1: PolyParam =>
def flagNothingBound = {
@@ -381,7 +377,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
}
else // fast path, in particular for refinements resulting from parameterization.
isSubRefinements(tp1w.asInstanceOf[RefinedType], tp2, skipped2) &&
- isSubType(tp1, skipped2) // TODO swap?
+ isSubType(tp1, skipped2)
}
compareRefined
case tp2: RecType =>
@@ -547,9 +543,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
* - `B` satisfies predicate `p`.
*/
private def testLifted(tp1: Type, tp2: Type, tparams: List[MemberBinding], p: Type => Boolean): Boolean = {
- val classBounds =
- if (Config.newHK) tp2.classSymbols
- else tp2.member(tpnme.hkApplyOBS).info.classSymbols
+ val classBounds = tp2.classSymbols
def recur(bcs: List[ClassSymbol]): Boolean = bcs match {
case bc :: bcs1 =>
val baseRef = tp1.baseTypeRef(bc)
@@ -564,61 +558,6 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
recur(tp1.baseClasses)
}
- /** If `projection` is a hk projection T#$apply with a constrainable poly param
- * as type constructor and `other` is not a hk projection, then 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 `projection`,
- * - has the same number of type parameters than `projection`
- * - has type parameter variances which conform to those of `projection`.
- * 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 `projection <: other` else test `other <: projection`.
- */
- def compareHkApplyOBS(projection: NamedType, other: Type, inOrder: Boolean): Boolean = {
- def tryInfer(tp: Type): Boolean = ctx.traceIndented(i"compareHK($projection, $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.isEtaExpandable && tycon.typeParams.nonEmpty =>
- val (ok, projection1) =
- if (ctx.mode.is(Mode.TypevarsMissContext))
- (true, EtaExpansion(tycon).appliedTo(projection.argInfos))
- else
- (tryInstantiate(param, EtaExpansion(tycon)), projection)
- ok &&
- (if (inOrder) isSubType(projection1, other) else isSubType(other, projection1))
- case _ =>
- false
- }
- }
- val hkTypeParams = param.typeParams
- subtyping.println(i"classBounds = ${projection.prefix.member(tpnme.hkApplyOBS).info.classSymbols}")
- subtyping.println(i"base classes = ${other.baseClasses}")
- subtyping.println(i"type params = ${hkTypeParams.map(_.memberName)}")
- if (inOrder) unifyWith(other)
- else testLifted(other, projection.prefix, hkTypeParams, unifyWith)
- case _ =>
- false
- }
- }
- !Config.newHK && projection.name == tpnme.hkApplyOBS && !other.isHKApply &&
- tryInfer(projection.prefix.typeConstructor.dealias)
- }
-
/** Handle subtype tests
*
* app <:< other if inOrder = true
@@ -695,7 +634,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
false
}
}
- Config.newHK && app.isHKApply && !other.isHKApply && {
+ app.isHKApply && !other.isHKApply && {
val reduced = if (inOrder) app else app.normalizeHkApply
if (reduced ne app)
if (inOrder) isSubType(reduced, other) else isSubType(other, reduced)
@@ -824,10 +763,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
* rebase both itself and the member info of `tp` on a freshly created skolem type.
*/
protected def hasMatchingMember(name: Name, tp1: Type, tp2: RefinedType): Boolean = {
- val rebindNeeded = tp2.refinementRefersToThis
- val base = if (rebindNeeded) ensureStableSingleton(tp1) else tp1
- val rinfo2 = if (rebindNeeded) tp2.refinedInfo.substRefinedThis(tp2, base) else tp2.refinedInfo
- val mbr = base.member(name)
+ val rinfo2 = tp2.refinedInfo
+ val mbr = tp1.member(name)
def qualifies(m: SingleDenotation) = isSubType(m.info, rinfo2)
@@ -843,15 +780,13 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
def selfReferentialMatch = tp1.isInstanceOf[SingletonType] && {
rinfo2 match {
case rinfo2: TypeAlias =>
- !defn.isBottomType(base.widen) && (base select name) =:= rinfo2.alias
+ !defn.isBottomType(tp1.widen) && (tp1 select name) =:= rinfo2.alias
case _ => false
}
}
- def varianceMatches = true // TODO: fill in
-
- /*>|>*/ ctx.traceIndented(i"hasMatchingMember($base . $name :? ${tp2.refinedInfo}) ${mbr.info.show} $rinfo2", subtyping) /*<|<*/ {
- (memberMatches || selfReferentialMatch) && varianceMatches
+ /*>|>*/ ctx.traceIndented(i"hasMatchingMember($tp1 . $name :? ${tp2.refinedInfo}) ${mbr.info.show} $rinfo2", subtyping) /*<|<*/ {
+ memberMatches || selfReferentialMatch
}
}
@@ -870,10 +805,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
* @return The parent type of `tp2` after skipping the matching refinements.
*/
private def skipMatching(tp1: Type, tp2: RefinedType): Type = tp1 match {
- case tp1 @ RefinedType(parent1, name1, rinfo1: TypeAlias)
- if name1 == tp2.refinedName &&
- !tp2.refinementRefersToThis &&
- !tp1.refinementRefersToThis =>
+ case tp1 @ RefinedType(parent1, name1, rinfo1: TypeAlias) if name1 == tp2.refinedName =>
tp2.parent match {
case parent2: RefinedType => skipMatching(parent1, parent2)
case parent2 => parent2
@@ -1224,39 +1156,29 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
* allowing both interpretations. A possible remedy is to be somehow stricter
* in where we allow which interpretation.
*/
- private def liftIfHK(tp1: Type, tp2: Type, op: (Type, Type) => Type) =
- if (Config.newHK) {
- val tparams1 = tp1.typeParams
- val tparams2 = tp2.typeParams
- if (tparams1.isEmpty || tparams2.isEmpty) op(tp1, tp2)
- else if (tparams1.length != tparams2.length) mergeConflict(tp1, tp2)
- else {
- val bindings: List[RecType => TypeBounds] =
- (tparams1, tparams2).zipped.map { (tparam1, tparam2) =>
- val b1: RecType => TypeBounds =
- tparam1.memberBoundsAsSeenFrom(tp1).recursify(tparams1)
- val b2: RecType => TypeBounds =
- tparam2.memberBoundsAsSeenFrom(tp2).recursify(tparams2)
- (rt: RecType) => (b1(rt) & b2(rt))
- .withBindingKind(
- BindingKind.fromVariance(
- (tparam1.memberVariance + tparam2.memberVariance) / 2))
- }
- val app1: RecType => Type = rt => tp1.appliedTo(argRefs(rt, tparams1.length))
- val app2: RecType => Type = rt => tp2.appliedTo(argRefs(rt, tparams2.length))
- val body: RecType => Type = rt => op(app1(rt), app2(rt))
- TypeLambda(bindings, body)
- }
- }
+ private def liftIfHK(tp1: Type, tp2: Type, op: (Type, Type) => Type) = {
+ val tparams1 = tp1.typeParams
+ val tparams2 = tp2.typeParams
+ if (tparams1.isEmpty || tparams2.isEmpty) op(tp1, tp2)
+ else if (tparams1.length != tparams2.length) mergeConflict(tp1, tp2)
else {
- val tparams1 = tp1.typeParamSymbols
- val tparams2 = tp2.typeParamSymbols
- def onlyNamed(tparams: List[TypeSymbol]) = tparams.forall(!_.is(ExpandedName))
- if (tparams1.isEmpty || tparams2.isEmpty ||
- onlyNamed(tparams1) && onlyNamed(tparams2)) op(tp1, tp2)
- else if (tparams1.length != tparams2.length) mergeConflict(tp1, tp2)
- else hkCombineOBS(tp1, tp2, tparams1, tparams2, op)
+ val bindings: List[RecType => TypeBounds] =
+ (tparams1, tparams2).zipped.map { (tparam1, tparam2) =>
+ val b1: RecType => TypeBounds =
+ tparam1.memberBoundsAsSeenFrom(tp1).recursify(tparams1)
+ val b2: RecType => TypeBounds =
+ tparam2.memberBoundsAsSeenFrom(tp2).recursify(tparams2)
+ (rt: RecType) => (b1(rt) & b2(rt))
+ .withBindingKind(
+ BindingKind.fromVariance(
+ (tparam1.memberVariance + tparam2.memberVariance) / 2))
+ }
+ val app1: RecType => Type = rt => tp1.appliedTo(argRefs(rt, tparams1.length))
+ val app2: RecType => Type = rt => tp2.appliedTo(argRefs(rt, tparams2.length))
+ val body: RecType => Type = rt => op(app1(rt), app2(rt))
+ TypeLambda(bindings, body)
}
+ }
/** Try to distribute `&` inside type, detect and handle conflicts
* @pre !(tp1 <: tp2) && !(tp2 <:< tp1) -- these cases were handled before
@@ -1268,10 +1190,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case tp1: RefinedType =>
tp2 match {
case tp2: RefinedType if tp1.refinedName == tp2.refinedName =>
- tp1.derivedRefinedType(
- tp1.parent & tp2.parent,
- tp1.refinedName,
- tp1.refinedInfo & tp2.refinedInfo.substRefinedThis(tp2, RefinedThis(tp1)))
+ tp1.derivedRefinedType(tp1.parent & tp2.parent, tp1.refinedName, tp1.refinedInfo & tp2.refinedInfo)
case _ =>
NoType
}
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index ca49d3d3c..6b75b574e 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -228,7 +228,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
return tp1.derivedRefinedType(
approximateUnion(OrType(tp1.parent, tp2.parent)),
tp1.refinedName,
- homogenizedUnion(tp1.refinedInfo, tp2.refinedInfo).substRefinedThis(tp2, RefinedThis(tp1)))
+ homogenizedUnion(tp1.refinedInfo, tp2.refinedInfo))
//.ensuring { x => println(i"approx or $tp1 | $tp2 = $x\n constr = ${ctx.typerState.constraint}"); true } // DEBUG
case _ =>
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 2120706f6..cd1b5739d 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -51,7 +51,7 @@ object Types {
* | | +--- SuperType
* | | +--- ConstantType
* | | +--- MethodParam
- * | | +----RefinedThis
+ * | | +----RecThis
* | | +--- SkolemType
* | +- PolyParam
* | +- RefinedOrRecType -+-- RefinedType
@@ -507,9 +507,7 @@ object Types {
}
def goRefined(tp: RefinedType) = {
val pdenot = go(tp.parent)
- val rinfo =
- if (tp.refinementRefersToThis) tp.refinedInfo.substRefinedThis(tp, pre)
- else tp.refinedInfo
+ val rinfo = tp.refinedInfo
if (name.isTypeName) { // simplified case that runs more efficiently
val jointInfo =
if (rinfo.isAlias) rinfo
@@ -577,6 +575,7 @@ object Types {
ctx.pendingMemberSearches = name :: ctx.pendingMemberSearches
}
+ //assert(ctx.findMemberCount < 20)
try go(this)
catch {
case ex: Throwable =>
@@ -964,62 +963,14 @@ object Types {
*
* P { type T = String, type R = P{...}.T } # R --> String
*
- * (2) The refinement is a fully instantiated type lambda, and the projected name is "$apply".
- * In this case the rhs of the apply is returned with all references to lambda argument types
- * substituted by their definitions.
- *
* (*) normalizes means: follow instantiated typevars and aliases.
*/
def lookupRefined(name: Name)(implicit ctx: Context): Type = {
def loop(pre: Type): Type = pre.stripTypeVar match {
case pre: RefinedType =>
- object instantiate extends TypeMap {
- var isSafe = true
- def apply(tp: Type): Type =
- if (!isSafe) tp
- else tp match {
- case TypeRef(RefinedThis(`pre`), name) if name.isHkArgName =>
- member(name).info match {
- case TypeAlias(alias) => alias
- case _ => isSafe = false; tp
- }
- case tp: TypeVar if !tp.inst.exists =>
- isSafe = false
- tp
- case _ =>
- mapOver(tp)
- }
- }
- def instArg(tp: Type): Type = tp match {
- case tp @ TypeAlias(TypeRef(RefinedThis(`pre`), name)) if name.isHkArgName =>
- member(name).info match {
- case TypeAlias(alias) => tp.derivedTypeAlias(alias) // needed to keep variance
- case bounds => bounds
- }
- case _ =>
- instantiate(tp)
- }
- def instTop(tp: Type): Type = tp.stripTypeVar match {
- case tp: RefinedType =>
- tp.derivedRefinedType(instTop(tp.parent), tp.refinedName, instArg(tp.refinedInfo))
- case _ =>
- instantiate(tp)
- }
- /** Reduce rhs of $hkApply to make it stand alone */
- def betaReduce(tp: Type) = {
- val reduced = instTop(tp)
- if (instantiate.isSafe) reduced else NoType
- }
pre.refinedInfo match {
case TypeAlias(alias) =>
- if (pre.refinedName ne name) loop(pre.parent)
- else alias match {
- case TypeRef(RefinedThis(`pre`), aliasName) => lookupRefined(aliasName) // (1)
- case _ =>
- if (!pre.refinementRefersToThis) alias
- else if (name == tpnme.hkApplyOBS) betaReduce(alias)
- else NoType
- }
+ if (pre.refinedName ne name) loop(pre.parent) else alias
case _ => loop(pre.parent)
}
case pre: RecType =>
@@ -1029,8 +980,6 @@ object Types {
candidate
}
else NoType
- case RefinedThis(binder) =>
- binder.lookupRefined(name)
case SkolemType(tp) =>
tp.lookupRefined(name)
case pre: WildcardType =>
@@ -1219,10 +1168,6 @@ object Types {
final def substThisUnlessStatic(cls: ClassSymbol, tp: Type)(implicit ctx: Context): Type =
if (cls.isStaticOwner) this else ctx.substThis(this, cls, tp, null)
- /** Substitute all occurrences of `SkolemType(binder)` by `tp` */
- final def substRefinedThis(binder: Type, tp: Type)(implicit ctx: Context): Type =
- ctx.substRefinedThis(this, binder, tp, null)
-
/** Substitute all occurrences of `RecThis(binder)` by `tp` */
final def substRecThis(binder: RecType, tp: Type)(implicit ctx: Context): Type =
ctx.substRecThis(this, binder, tp, null)
@@ -1643,7 +1588,7 @@ object Types {
* to an (unbounded) wildcard type.
*
* (2) Reduce a type-ref `T { X = U; ... } # X` to `U`
- * provided `U` does not refer with a RefinedThis to the
+ * provided `U` does not refer with a RecThis to the
* refinement type `T { X = U; ... }`
*/
def reduceProjection(implicit ctx: Context): Type = {
@@ -1715,13 +1660,6 @@ object Types {
else if (isType) {
val res = prefix.lookupRefined(name)
if (res.exists) res
- else if (name == tpnme.hkApplyOBS && prefix.classNotLambda) {
- // After substitution we might end up with a type like
- // `C { type hk$0 = T0; ...; type hk$n = Tn } # $Apply`
- // where C is a class. In that case we eta expand `C`.
- if (defn.isBottomType(prefix)) prefix.classSymbol.typeRef
- else derivedSelect(prefix.EtaExpandCore)
- }
else if (Config.splitProjections)
prefix match {
case prefix: AndType =>
@@ -1999,9 +1937,7 @@ object Types {
}
object TypeRef {
- def checkProjection(prefix: Type, name: TypeName)(implicit ctx: Context) =
- if (name == tpnme.hkApplyOBS && prefix.classNotLambda)
- assert(false, s"bad type : $prefix.$name does not allow $$Apply projection")
+ def checkProjection(prefix: Type, name: TypeName)(implicit ctx: Context) = ()
/** Create type ref with given prefix and name */
def apply(prefix: Type, name: TypeName)(implicit ctx: Context): TypeRef = {
@@ -2128,34 +2064,15 @@ object Types {
* @param infoFn: A function that produces the info of the refinement declaration,
* given the refined type itself.
*/
- abstract case class RefinedType(private var myParent: Type, refinedName: Name, private var myRefinedInfo: Type)
+ abstract case class RefinedType(parent: Type, refinedName: Name, refinedInfo: Type)
extends RefinedOrRecType with BindingType with MemberBinding {
- final def parent = myParent
- final def refinedInfo = myRefinedInfo
-
- private var refinementRefersToThisCache: Boolean = _
- private var refinementRefersToThisKnown: Boolean = false
-
- def refinementRefersToThis(implicit ctx: Context): Boolean = {
- if (!refinementRefersToThisKnown) {
- refinementRefersToThisCache = refinedInfo.containsRefinedThis(this)
- refinementRefersToThisKnown = true
- }
- refinementRefersToThisCache
- }
-
override def underlying(implicit ctx: Context) = parent
private def badInst =
throw new AssertionError(s"bad instantiation: $this")
def checkInst(implicit ctx: Context): this.type = {
- if (refinedName == tpnme.hkApplyOBS)
- parent.stripTypeVar match {
- case RefinedType(_, name, _) if name.isHkArgName => // ok
- case _ => badInst
- }
this
}
@@ -2197,9 +2114,15 @@ object Types {
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
- RefinedType(parent, refinedName, rt => refinedInfo.substRefinedThis(this, RefinedThis(rt)))
- .betaReduce
+ else {
+ // `normalizedRefinedInfo` is `refinedInfo` reduced everywhere via `reduceProjection`.
+ // (this is achieved as a secondary effect of substRecThis).
+ // It turns out this normalization is now needed; without it there's
+ // 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).betaReduce
+ }
/** Add this refinement to `parent`, provided If `refinedName` is a member of `parent`. */
def wrapIfMember(parent: Type)(implicit ctx: Context): Type =
@@ -2232,36 +2155,16 @@ object Types {
override def toString = s"RefinedType($parent, $refinedName, $refinedInfo)"
}
- class CachedRefinedType(refinedName: Name) extends RefinedType(NoType, refinedName, NoType)
-
- class PreHashedRefinedType(parent: Type, refinedName: Name, refinedInfo: Type, hc: Int)
+ class CachedRefinedType(parent: Type, refinedName: Name, refinedInfo: Type, hc: Int)
extends RefinedType(parent, refinedName, refinedInfo) {
myHash = hc
override def computeHash = unsupported("computeHash")
}
object RefinedType {
- def make(parent: Type, names: List[Name], infoFns: List[RefinedType => Type])(implicit ctx: Context): Type =
+ def make(parent: Type, names: List[Name], infos: List[Type])(implicit ctx: Context): Type =
if (names.isEmpty) parent
- else make(RefinedType(parent, names.head, infoFns.head), names.tail, infoFns.tail)
-
- def recursive(parentFn: RefinedType => Type, names: List[Name], infoFns: List[RefinedType => Type])(implicit ctx: Context): RefinedType = {
- val refinements: List[RefinedType] = names.map(new CachedRefinedType(_))
- val last = refinements.last
- (refinements, infoFns).zipped.foreach((rt, infoFn) => rt.myRefinedInfo = infoFn(last))
- (parentFn(last) /: refinements) { (parent, rt) =>
- rt.myParent = parent
- ctx.base.uniqueRefinedTypes.enterIfNew(rt).checkInst
- }.asInstanceOf[RefinedType]
- }
-
- def apply(parent: Type, name: Name, infoFn: RefinedType => Type)(implicit ctx: Context): RefinedType = {
- assert(!ctx.erasedTypes || ctx.mode.is(Mode.Printing))
- val res: RefinedType = new CachedRefinedType(name)
- res.myParent = parent
- res.myRefinedInfo = infoFn(res)
- ctx.base.uniqueRefinedTypes.enterIfNew(res).checkInst
- }
+ else make(RefinedType(parent, names.head, infos.head), names.tail, infos.tail)
def apply(parent: Type, name: Name, info: Type)(implicit ctx: Context): RefinedType = {
assert(!ctx.erasedTypes)
@@ -2722,7 +2625,7 @@ object Types {
}
}
- // ----- Bound types: MethodParam, PolyParam, RefinedThis --------------------------
+ // ----- Bound types: MethodParam, PolyParam --------------------------
abstract class BoundType extends CachedProxyType with ValueType {
type BT <: Type
@@ -2806,22 +2709,6 @@ object Types {
}
}
- /** a this-reference to an enclosing refined type `binder`. */
- case class RefinedThis(binder: RefinedType) extends BoundType with SingletonType {
- type BT = RefinedType
- override def underlying(implicit ctx: Context) = binder
- def copyBoundType(bt: BT) = RefinedThis(bt)
-
- // need to customize hashCode and equals to prevent infinite recursion for
- // refinements that refer to the refinement type via this
- override def computeHash = addDelta(binder.identityHash, 41)
- override def equals(that: Any) = that match {
- case that: RefinedThis => this.binder eq that.binder
- case _ => false
- }
- override def toString = s"RefinedThis(${binder.hashCode})"
- }
-
/** a self-reference to an enclosing recursive type. */
case class RecThis(binder: RecType) extends BoundType with SingletonType {
type BT = RecType
@@ -3892,6 +3779,8 @@ object Types {
class MergeError(msg: String, val tp1: Type, val tp2: Type) extends TypeError(msg)
+ @sharable val dummyRec = new RecType(rt => NoType)
+
// ----- Debug ---------------------------------------------------------
@sharable var debugTrace = false
diff --git a/src/dotty/tools/dotc/core/Uniques.scala b/src/dotty/tools/dotc/core/Uniques.scala
index b00508d60..cb9670c69 100644
--- a/src/dotty/tools/dotc/core/Uniques.scala
+++ b/src/dotty/tools/dotc/core/Uniques.scala
@@ -107,8 +107,8 @@ object Uniques {
def enterIfNew(parent: Type, refinedName: Name, refinedInfo: Type): RefinedType = {
val h = doHash(refinedName, refinedInfo, parent)
- def newType = new PreHashedRefinedType(parent, refinedName, refinedInfo, h)
- if (monitored) recordCaching(h, classOf[PreHashedRefinedType])
+ def newType = new CachedRefinedType(parent, refinedName, refinedInfo, h)
+ if (monitored) recordCaching(h, classOf[CachedRefinedType])
if (h == NotCached) newType
else {
val r = findPrevious(h, parent, refinedName, refinedInfo)
diff --git a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
index e9708961a..38d55e0e8 100644
--- a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
+++ b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
@@ -259,8 +259,7 @@ object TastyFormat {
final val TYPEREFdirect = 66
final val TERMREFpkg = 67
final val TYPEREFpkg = 68
- final val REFINEDthis = 69
- final val RECthis = REFINEDthis // !!!
+ final val RECthis = 69
final val BYTEconst = 70
final val SHORTconst = 71
final val CHARconst = 72
diff --git a/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/src/dotty/tools/dotc/core/tasty/TreePickler.scala
index 9be5c8bcf..d6e6c4d6b 100644
--- a/src/dotty/tools/dotc/core/tasty/TreePickler.scala
+++ b/src/dotty/tools/dotc/core/tasty/TreePickler.scala
@@ -211,11 +211,6 @@ class TreePickler(pickler: TastyPickler) {
case tpe: SuperType =>
writeByte(SUPERtype)
withLength { pickleType(tpe.thistpe); pickleType(tpe.supertpe)}
- case tpe: RefinedThis =>
- writeByte(REFINEDthis)
- val binderAddr = pickledTypes.get(tpe.binder)
- assert(binderAddr != null, tpe.binder)
- writeRef(binderAddr.asInstanceOf[Addr])
case tpe: RecThis =>
writeByte(RECthis)
val binderAddr = pickledTypes.get(tpe.binder)
diff --git a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
index d9a062263..2d230c630 100644
--- a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
+++ b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
@@ -260,7 +260,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
val parent = readType()
val ttag = nextUnsharedTag
if (ttag == TYPEBOUNDS || ttag == TYPEALIAS) name = name.toTypeName
- RefinedType(parent, name, rt => registeringType(rt, readType()))
+ RefinedType(parent, name, readType())
// Note that the lambda "rt => ..." is not equivalent to a wildcard closure!
// Eta expansion of the latter puts readType() out of the expression.
case APPLIEDtype =>
@@ -325,8 +325,6 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
readPackageRef().termRef
case TYPEREF =>
val name = readName().toTypeName
- if (name.isLambdaTraitNameOBS) // Make sure corresponding lambda trait exists
- defn.LambdaTraitOBS(name.lambdaTraitVariancesOBS)
TypeRef(readType(), name)
case TERMREF =>
readNameSplitSig() match {
@@ -337,11 +335,8 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
ThisType.raw(readType().asInstanceOf[TypeRef])
case RECtype =>
RecType(rt => registeringType(rt, readType()))
- case REFINEDthis =>
- readTypeRef() match {
- case t: RefinedType => RefinedThis(t)
- case t: RecType => RecThis(t)
- }
+ case RECthis =>
+ RecThis(readTypeRef().asInstanceOf[RecType])
case SHARED =>
val ref = readAddr()
typeAtAddr.getOrElseUpdate(ref, forkAt(ref).readType())
diff --git a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
index 557a9df74..18a4e83b6 100644
--- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
+++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
@@ -632,8 +632,6 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
case info =>
tp.derivedRefinedType(parent1, name, info)
}
- case tp @ TypeRef(pre, tpnme.hkApplyOBS) =>
- tp.derivedSelect(elim(pre))
case _ =>
tp
}
diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala
index a9f5b771a..a8888fd3c 100644
--- a/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -50,9 +50,6 @@ class PlainPrinter(_ctx: Context) extends Printer {
homogenize(tp1) & homogenize(tp2)
case OrType(tp1, tp2) =>
homogenize(tp1) | homogenize(tp2)
- case tp @ TypeRef(_, tpnme.hkApplyOBS) =>
- val tp1 = tp.reduceProjection
- if (tp1 eq tp) tp else homogenize(tp1)
case tp: RefinedType =>
tp.normalizeHkApply
case tp: SkolemType =>
@@ -250,8 +247,6 @@ class PlainPrinter(_ctx: Context) extends Printer {
val idx = openRecs.reverse.indexOf(tp.binder)
if (idx >= 0) selfRecName(idx + 1)
else "{...}.this" // TODO move underlying type to an addendum, e.g. ... z3 ... where z3: ...
- case tp: RefinedThis =>
- s"${nameString(tp.binder.typeSymbol)}{...}.this"
case tp: SkolemType =>
if (homogenizedView) toText(tp.info) else tp.repr
}
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index 61e29982b..3da977b31 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -118,9 +118,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
if (defn.isTupleClass(cls)) return toTextTuple(args)
return (toTextLocal(tycon) ~ "[" ~ Text(args map argText, ", ") ~ "]").close
case tp @ TypeLambda(argBoundss, body) =>
- val variances =
- if (Config.newHK) argBoundss.map(b => BindingKind.toVariance(b.bindingKind))
- else tp.classSymbol.typeParams.map(_.variance)
+ 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 {
diff --git a/src/dotty/tools/dotc/sbt/ExtractAPI.scala b/src/dotty/tools/dotc/sbt/ExtractAPI.scala
index c0a3c3dfe..d4b38c66e 100644
--- a/src/dotty/tools/dotc/sbt/ExtractAPI.scala
+++ b/src/dotty/tools/dotc/sbt/ExtractAPI.scala
@@ -403,8 +403,8 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
apiType(tpe)
case tp: ThisType =>
apiThis(tp.cls)
- case RefinedThis(binder) =>
- apiThis(binder.typeSymbol)
+ case RecThis(binder) =>
+ apiThis(binder.typeSymbol) // !!! this is almost certainly wrong !!!
case tp: ParamType =>
new api.ParameterRef(tp.paramName.toString)
case tp: LazyRef =>
diff --git a/src/dotty/tools/dotc/sbt/ExtractDependencies.scala b/src/dotty/tools/dotc/sbt/ExtractDependencies.scala
index 1f19a1058..026a518ce 100644
--- a/src/dotty/tools/dotc/sbt/ExtractDependencies.scala
+++ b/src/dotty/tools/dotc/sbt/ExtractDependencies.scala
@@ -163,8 +163,7 @@ private class ExtractDependenciesCollector(implicit val ctx: Context) extends tp
sym.eq(NoSymbol) ||
sym.isEffectiveRoot ||
sym.isAnonymousFunction ||
- sym.isAnonymousClass ||
- sym.isLambdaTraitOBS
+ sym.isAnonymousClass
private def addInheritanceDependency(sym: Symbol): Unit =
_topLevelInheritanceDependencies += sym.topLevelClass
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index cdbf692cd..caae422d3 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -634,7 +634,6 @@ trait Applications extends Compatibility { self: Typer =>
typedFn.tpe.widen match {
case pt: PolyType =>
if (typedArgs.length <= pt.paramBounds.length && !isNamed)
- typedArgs = typedArgs.zipWithConserve(pt.paramBounds)(adaptTypeArg)
if (typedFn.symbol == defn.Predef_classOf && typedArgs.nonEmpty) {
val arg = typedArgs.head
checkClassType(arg.tpe, arg.pos, traitReq = false, stablePrefixReq = false)
@@ -644,9 +643,6 @@ trait Applications extends Compatibility { self: Typer =>
assignType(cpy.TypeApply(tree)(typedFn, typedArgs), typedFn, typedArgs)
}
- def adaptTypeArg(tree: tpd.Tree, bound: Type)(implicit ctx: Context): tpd.Tree =
- if (Config.newHK) tree else tree.withType(tree.tpe.etaExpandIfHK(bound))
-
/** Rewrite `new Array[T](....)` if T is an unbounded generic to calls to newGenericArray.
* It is performed during typer as creation of generic arrays needs a classTag.
* we rely on implicit search to find one.
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index 1b02f7e70..a5246cf6b 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -284,13 +284,10 @@ trait ImplicitRunInfo { self: RunInfo =>
override implicit protected val ctx: Context = liftingCtx
override def stopAtStatic = true
def apply(tp: Type) = tp match {
- case tp: TypeRef if tp.symbol.isLambdaTraitOBS =>
- defn.AnyType
case tp: TypeRef if tp.symbol.isAbstractOrAliasType =>
val pre = tp.prefix
def joinClass(tp: Type, cls: ClassSymbol) =
- if (cls.isLambdaTraitOBS) tp
- else AndType.make(tp, cls.typeRef.asSeenFrom(pre, cls.owner))
+ AndType.make(tp, cls.typeRef.asSeenFrom(pre, cls.owner))
val lead = if (tp.prefix eq NoPrefix) defn.AnyType else apply(tp.prefix)
(lead /: tp.classSymbols)(joinClass)
case tp: TypeVar =>
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index bc8f8e281..bf36942e0 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -973,29 +973,6 @@ class Namer { typer: Typer =>
}
ensureUpToDate(sym.typeRef, dummyInfo)
ensureUpToDate(sym.typeRef.appliedTo(tparamSyms.map(_.typeRef)), TypeBounds.empty)
-
- if (Config.newHK) sym.info
- else etaExpandArgsOBS.apply(sym.info)
- }
-
- /** Eta expand all class types C appearing as arguments to a higher-kinded
- * type parameter to type lambdas, e.g. [HK0] => C[HK0]. This is necessary
- * because in `typedAppliedTypeTree` we might have missed some eta expansions
- * of arguments in F-bounds, because the recursive type was initialized with
- * TypeBounds.empty.
- */
- def etaExpandArgsOBS(implicit ctx: Context) = new TypeMap {
- def apply(tp: Type): Type = tp match {
- case tp: RefinedType =>
- val args = tp.argInfos.mapconserve(this)
- if (args.nonEmpty) {
- val tycon = tp.withoutArgs(args)
- val tycon1 = this(tycon)
- val tparams = tycon.typeParams
- val args1 = if (args.length == tparams.length) etaExpandIfHK(tparams, args) else args
- if ((tycon1 eq tycon) && (args1 eq args)) tp else tycon1.appliedTo(args1)
- } else mapOver(tp)
- case _ => mapOver(tp)
- }
+ sym.info
}
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 96bc2ab35..2ab06bf70 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -949,8 +949,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
(if (isVarPattern(arg)) desugar.patternVar(arg) else arg, tparam.memberBounds)
else
(arg, WildcardType)
- val arg1 = typed(desugaredArg, argPt)
- adaptTypeArg(arg1, tparam.memberBounds)
+ typed(desugaredArg, argPt)
}
args.zipWithConserve(tparams)(typedArg(_, _)).asInstanceOf[List[Tree]]
}