aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Types.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/core/Types.scala')
-rw-r--r--src/dotty/tools/dotc/core/Types.scala57
1 files changed, 40 insertions, 17 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 4885b30d8..289515ae1 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -813,11 +813,15 @@ object Types {
if (from1.isEmpty) ctx.subst1(this, from.head, to.head, null)
else {
val from2 = from1.tail
- if (from2.isEmpty) ctx.subst2(this, from.head, to.head, from.tail.head, to.tail.head, null)
+ if (from2.isEmpty) ctx.subst2(this, from.head, to.head, from1.head, to.tail.head, null)
else ctx.subst(this, from, to, null)
}
}
+/* Not needed yet:
+ final def substDealias(from: List[Symbol], to: List[Type])(implicit ctx: Context): Type =
+ new ctx.SubstDealiasMap(from, to).apply(this)
+*/
/** Substitute all types of the form `PolyParam(from, N)` by
* `PolyParam(to, N)`.
*/
@@ -1602,17 +1606,22 @@ object Types {
// and therefore two different poly types would never be equal.
/** A trait that mixes in functionality for signature caching */
- trait SignedType extends Type {
+ trait MethodicType extends Type {
private[this] var mySignature: Signature = _
private[this] var mySignatureRunId: Int = NoRunId
protected def computeSignature(implicit ctx: Context): Signature
- protected def resultSignature(implicit ctx: Context) = resultType match {
- case rtp: SignedType => rtp.signature
+ protected def resultSignature(implicit ctx: Context) = try resultType match {
+ case rtp: MethodicType => rtp.signature
case tp => Signature(tp, isJava = false)
}
+ catch {
+ case ex: AssertionError =>
+ println(i"failure while taking result signture of $resultType")
+ throw ex
+ }
final override def signature(implicit ctx: Context): Signature = {
if (ctx.runId != mySignatureRunId) {
@@ -1623,7 +1632,7 @@ object Types {
}
}
- trait MethodOrPoly extends SignedType
+ trait MethodOrPoly extends MethodicType
abstract case class MethodType(paramNames: List[TermName], paramTypes: List[Type])
(resultTypeExp: MethodType => Type)
@@ -1717,6 +1726,8 @@ object Types {
def apply(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType
def apply(paramNames: List[TermName], paramTypes: List[Type], resultType: Type)(implicit ctx: Context): MethodType =
apply(paramNames, paramTypes)(_ => resultType)
+ def apply(paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType =
+ apply(nme.syntheticParamNames(paramTypes.length), paramTypes)(resultTypeExp)
def apply(paramTypes: List[Type], resultType: Type)(implicit ctx: Context): MethodType =
apply(nme.syntheticParamNames(paramTypes.length), paramTypes, resultType)
def fromSymbols(params: List[Symbol], resultType: Type)(implicit ctx: Context) = {
@@ -1748,7 +1759,7 @@ object Types {
}
abstract case class ExprType(override val resultType: Type)
- extends CachedProxyType with TermType with SignedType {
+ extends CachedProxyType with TermType with MethodicType {
override def underlying(implicit ctx: Context): Type = resultType
protected def computeSignature(implicit ctx: Context): Signature = resultSignature
def derivedExprType(resultType: Type)(implicit ctx: Context) =
@@ -2019,19 +2030,31 @@ object Types {
decls: Scope,
selfInfo: DotClass /* should be: Type | Symbol */) extends CachedGroundType with TypeType {
- def selfType(implicit ctx: Context): Type = selfInfo match {
- case NoType =>
- if (selfTypeCache == null) selfTypeCache = computeSelfType(cls.typeRef, cls.typeParams)
- selfTypeCache
- case tp: Type => tp
- case self: Symbol => self.info
+ /** The self type of a class is the conjunction of
+ * - the explicit self type if given (or the info of a given self symbol), and
+ * - the fully applied reference to the class itself.
+ */
+ def selfType(implicit ctx: Context): Type = {
+ if (selfTypeCache == null) {
+ def fullRef = fullyAppliedRef(cls.typeRef, cls.typeParams)
+ selfTypeCache = selfInfo match {
+ case NoType =>
+ fullRef
+ case tp: Type =>
+ if (cls is Module) tp else AndType(tp, fullRef)
+ case self: Symbol =>
+ assert(!(cls is Module))
+ AndType(self.info, fullRef)
+ }
+ }
+ selfTypeCache
}
private var selfTypeCache: Type = null
- private def computeSelfType(base: Type, tparams: List[TypeSymbol])(implicit ctx: Context): Type = tparams match {
+ private def fullyAppliedRef(base: Type, tparams: List[TypeSymbol])(implicit ctx: Context): Type = tparams match {
case tparam :: tparams1 =>
- computeSelfType(
+ fullyAppliedRef(
RefinedType(base, tparam.name, TypeRef(cls.thisType, tparam).toBounds(tparam)),
tparams1)
case nil =>
@@ -2077,8 +2100,8 @@ object Types {
if (prefix eq this.prefix) this
else ClassInfo(prefix, cls, classParents, decls, selfInfo)
- def derivedClassInfo(prefix: Type = this.prefix, classParents: List[TypeRef] = classParents, selfInfo: DotClass = this.selfInfo)(implicit ctx: Context) =
- if ((prefix eq this.prefix) && (classParents eq this.classParents) && (selfInfo eq this.selfInfo)) this
+ def derivedClassInfo(prefix: Type = this.prefix, classParents: List[TypeRef] = classParents, decls: Scope = this.decls, selfInfo: DotClass = this.selfInfo)(implicit ctx: Context) =
+ if ((prefix eq this.prefix) && (classParents eq this.classParents) && (decls eq this.decls) && (selfInfo eq this.selfInfo)) this
else ClassInfo(prefix, cls, classParents, decls, selfInfo)
override def computeHash = doHash(cls, prefix)
@@ -2431,7 +2454,7 @@ object Types {
case self: Type => this(self)
case _ => tp.self
}
- tp.derivedClassInfo(prefix1, parents1, self1)
+ tp.derivedClassInfo(prefix1, parents1, tp.decls, self1)
}
}