diff options
Diffstat (limited to 'src/dotty/tools/dotc/core/Types.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 6b46e475b..109f39c2f 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -48,6 +48,7 @@ object Types { * | | +--- SuperType * | | +--- ConstantType * | | +--- MethodParam + * | | +----RefinedThis * | | +--- SkolemType * | +- PolyParam * | +- RefinedType @@ -438,7 +439,7 @@ object Types { def goRefined(tp: RefinedType) = { val pdenot = go(tp.parent) val rinfo = - if (tp.refinementRefersToThis) tp.refinedInfo.substSkolem(tp, pre) + if (tp.refinementRefersToThis) tp.refinedInfo.substRefinedThis(tp, pre) else tp.refinedInfo if (name.isTypeName) { // simplified case that runs more efficiently val jointInfo = @@ -583,7 +584,7 @@ object Types { */ final def asSeenFrom(pre: Type, cls: Symbol)(implicit ctx: Context): Type = track("asSeenFrom") { if (!cls.membersNeedAsSeenFrom(pre)) this - else ctx.asSeenFrom(this, pre, cls, null) + else ctx.asSeenFrom(this, pre, cls) } // ----- Subtype-related -------------------------------------------- @@ -822,7 +823,7 @@ object Types { object instantiate extends TypeMap { var isSafe = true def apply(tp: Type): Type = tp match { - case TypeRef(SkolemType(`pre`), name) if name.isLambdaArgName => + case TypeRef(RefinedThis(`pre`), name) if name.isLambdaArgName => val TypeAlias(alias) = member(name).info alias case tp: TypeVar if !tp.inst.exists => @@ -845,13 +846,15 @@ object Types { if (pre.refinedName ne name) loop(pre.parent, pre.refinedName :: resolved) else if (!pre.refinementRefersToThis) alias else alias match { - case TypeRef(SkolemType(`pre`), aliasName) => lookupRefined(aliasName) // (1) + case TypeRef(RefinedThis(`pre`), aliasName) => lookupRefined(aliasName) // (1) case _ => if (name == tpnme.Apply) betaReduce(alias) else NoType // (2) } case _ => loop(pre.parent, resolved) } - case SkolemType(binder) => + case RefinedThis(binder) => binder.lookupRefined(name) + case SkolemType(tp) => + tp.lookupRefined(name) case pre: WildcardType => WildcardType case pre: TypeRef => @@ -1024,8 +1027,8 @@ object Types { if (cls.isStaticOwner) this else ctx.substThis(this, cls, tp, null) /** Substitute all occurrences of `SkolemType(binder)` by `tp` */ - final def substSkolem(binder: Type, tp: Type)(implicit ctx: Context): Type = - ctx.substSkolem(this, binder, tp, null) + final def substRefinedThis(binder: Type, tp: Type)(implicit ctx: Context): Type = + ctx.substRefinedThis(this, binder, tp, null) /** Substitute a bound type by some other type */ final def substParam(from: ParamType, to: Type)(implicit ctx: Context): Type = @@ -1402,7 +1405,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 SkolemType to the + * provided `U` does not refer with a RefinedThis to the * refinement type `T { X = U; ... }` */ def reduceProjection(implicit ctx: Context): Type = { @@ -1816,7 +1819,7 @@ object Types { def refinementRefersToThis(implicit ctx: Context): Boolean = { if (!refinementRefersToThisKnown) { - refinementRefersToThisCache = refinedInfo.containsSkolemType(this) + refinementRefersToThisCache = refinedInfo.containsRefinedThis(this) refinementRefersToThisKnown = true } refinementRefersToThisCache @@ -1852,7 +1855,7 @@ object Types { derivedRefinedType(parent.EtaExpand, refinedName, refinedInfo) else if (false) RefinedType(parent, refinedName, refinedInfo) - else RefinedType(parent, refinedName, rt => refinedInfo.substSkolem(this, SkolemType(rt))) + else RefinedType(parent, refinedName, rt => refinedInfo.substRefinedThis(this, RefinedThis(rt))) } /** Add this refinement to `parent`, provided If `refinedName` is a member of `parent`. */ @@ -2236,7 +2239,7 @@ object Types { } } - // ----- Bound types: MethodParam, PolyParam, SkolemType -------------------------- + // ----- Bound types: MethodParam, PolyParam, RefinedThis -------------------------- abstract class BoundType extends CachedProxyType with ValueType { type BT <: Type @@ -2309,20 +2312,38 @@ object Types { } } - /** A skolem type reference with underlying type `binder`. */ - case class SkolemType(binder: Type) extends BoundType with SingletonType { - type BT = Type + /** 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) = SkolemType(bt) + 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: SkolemType => this.binder eq that.binder + case that: RefinedThis => this.binder eq that.binder case _ => false } - override def toString = s"SkolemType(${binder.hashCode})" + override def toString = s"RefinedThis(${binder.hashCode})" + } + + // ----- Skolem types ----------------------------------------------- + + /** A skolem type reference with underlying type `binder`. */ + abstract case class SkolemType(info: Type) extends CachedProxyType with ValueType with SingletonType { + override def underlying(implicit ctx: Context) = info + def derivedSkolemType(info: Type)(implicit ctx: Context) = + if (info eq this.info) this else SkolemType(info) + override def computeHash = doHash(info) + override def toString = s"Skolem($info)" + } + + final class CachedSkolemType(info: Type) extends SkolemType(info) + + object SkolemType { + def apply(info: Type)(implicit ctx: Context) = + unique(new CachedSkolemType(info)) } // ------------ Type variables ---------------------------------------- @@ -2883,6 +2904,9 @@ object Types { case tp: AndOrType => tp.derivedAndOrType(this(tp.tp1), this(tp.tp2)) + case tp: SkolemType => + tp.derivedSkolemType(this(tp.info)) + case tp @ AnnotatedType(annot, underlying) => val underlying1 = this(underlying) if (underlying1 eq underlying) tp else tp.derivedAnnotatedType(mapOver(annot), underlying1) @@ -3022,6 +3046,9 @@ object Types { case tp: AndOrType => this(this(x, tp.tp1), tp.tp2) + case tp: SkolemType => + this(x, tp.info) + case AnnotatedType(annot, underlying) => this(applyToAnnot(x, annot), underlying) |