diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 45 |
2 files changed, 33 insertions, 18 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index df18813b9..de42b3e5f 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -268,9 +268,7 @@ class TypeApplications(val self: Type) extends AnyVal { case _ => default } case tp @ RefinedType(parent, name) if !tp.member(name).symbol.is(ExpandedTypeParam) => - val pbase = parent.baseTypeWithArgs(base) - if (pbase.member(name).exists) RefinedType(pbase, name, tp.refinedInfo) - else pbase + tp.wrapIfMember(parent.baseTypeWithArgs(base)) case tp: TermRef => tp.underlying.baseTypeWithArgs(base) case AndType(tp1, tp2) => @@ -281,7 +279,7 @@ class TypeApplications(val self: Type) extends AnyVal { default } } - + /** Translate a type of the form From[T] to To[T], keep other types as they are. * `from` and `to` must be static classes, both with one type parameter, and the same variance. */ diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index e6235695e..fe95219b8 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -858,6 +858,13 @@ object Types { case _ => defn.AnyClass.typeRef } + /** the self type of the underlying classtype */ + def givenSelfType(implicit ctx: Context): Type = this match { + case tp @ RefinedType(parent, name) => tp.wrapIfMember(parent.givenSelfType) + case tp: TypeProxy => tp.underlying.givenSelfType + case _ => NoType + } + /** The parameter types of a PolyType or MethodType, Empty list for others */ final def paramTypess(implicit ctx: Context): List[List[Type]] = this match { case mt: MethodType => mt.paramTypes :: mt.resultType.paramTypess @@ -1781,7 +1788,12 @@ object Types { if (false) RefinedType(parent, refinedName, refinedInfo) else RefinedType(parent, refinedName, rt => refinedInfo.substSkolem(this, SkolemType(rt))) } - + + /** Add this refinement to `parent`, provided If `refinedName` is a member of `parent`. */ + def wrapIfMember(parent: Type)(implicit ctx: Context): Type = + if (parent.member(refinedName).exists) derivedRefinedType(parent, refinedName, refinedInfo) + else parent + override def equals(that: Any) = that match { case that: RefinedType => this.parent == that.parent && @@ -2398,22 +2410,27 @@ object Types { * - the fully applied reference to the class itself. */ def selfType(implicit ctx: Context): Type = { - if (selfTypeCache == null) { - def fullRef = fullyAppliedRef(cls.typeRef, cls.typeParams) - def withFullRef(tp: Type): Type = - if (ctx.erasedTypes) fullRef else AndType(tp, fullRef) - selfTypeCache = selfInfo match { - case NoType => - fullRef - case tp: Type => - if (cls is Module) tp else withFullRef(tp) - case self: Symbol => - assert(!(cls is Module)) - withFullRef(self.info) + if (selfTypeCache == null) + selfTypeCache = { + def fullRef = fullyAppliedRef(cls.typeRef, cls.typeParams) + val given = givenSelfType + val raw = + if (!given.exists) fullRef + else if (cls is Module) given + else if (ctx.erasedTypes) fullRef + else AndType(given, fullRef) + raw//.asSeenFrom(prefix, cls.owner) } - } selfTypeCache } + + /** The explicitly given self type (self types of modules are assumed to be + * explcitly given here). + */ + override def givenSelfType(implicit ctx: Context): Type = selfInfo match { + case tp: Type => tp + case self: Symbol => self.info + } private var selfTypeCache: Type = null |