aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala6
-rw-r--r--src/dotty/tools/dotc/core/Types.scala45
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