aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Types.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-06-29 19:59:16 +0200
committerMartin Odersky <odersky@gmail.com>2016-07-11 13:35:02 +0200
commitd1f809f14cad2c14c312767d71361c7f2e7d8244 (patch)
treea929f8d6c9700acfc5ae031fdda6bb0852c9726e /src/dotty/tools/dotc/core/Types.scala
parente749d832e9adebc502c961d743b3b29072f8116a (diff)
downloaddotty-d1f809f14cad2c14c312767d71361c7f2e7d8244.tar.gz
dotty-d1f809f14cad2c14c312767d71361c7f2e7d8244.tar.bz2
dotty-d1f809f14cad2c14c312767d71361c7f2e7d8244.zip
Remove old hk scheme
- Simplify RefinedType - Drop recursive definition of RefinedThis - this is now taken over by RecType. - Drop RefinedThis. - Simplify typeParams The logic avoiding forcing is no longer needed. - Remove unused code and out of date comments.
Diffstat (limited to 'src/dotty/tools/dotc/core/Types.scala')
-rw-r--r--src/dotty/tools/dotc/core/Types.scala155
1 files changed, 22 insertions, 133 deletions
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