aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-01-01 14:47:52 +0100
committerMartin Odersky <odersky@gmail.com>2015-01-01 14:49:33 +0100
commit95f74c2a999b20ee5f6ddbe6e14511872e8c227f (patch)
tree40ff60221d4a9e9ba8b9a4ea01b11eec036903a2 /src
parente3a43806a2b5b17982e942a82cabe139c09d971e (diff)
downloaddotty-95f74c2a999b20ee5f6ddbe6e14511872e8c227f.tar.gz
dotty-95f74c2a999b20ee5f6ddbe6e14511872e8c227f.tar.bz2
dotty-95f74c2a999b20ee5f6ddbe6e14511872e8c227f.zip
Provide the correct levels for RefinedThis types.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/core/Substituters.scala9
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala4
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala4
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala17
-rw-r--r--src/dotty/tools/dotc/core/Types.scala10
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala14
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala2
7 files changed, 38 insertions, 22 deletions
diff --git a/src/dotty/tools/dotc/core/Substituters.scala b/src/dotty/tools/dotc/core/Substituters.scala
index 205188507..119aca569 100644
--- a/src/dotty/tools/dotc/core/Substituters.scala
+++ b/src/dotty/tools/dotc/core/Substituters.scala
@@ -181,8 +181,13 @@ trait Substituters { this: Context =>
final def substThis(tp: Type, from: RefinedType, to: Type, theMap: SubstRefinedThisMap): Type =
tp match {
- case tp @ RefinedThis(rt, _) =>
- if (rt eq from) to else tp
+ case tp @ RefinedThis(rt, level) =>
+ if (rt eq from)
+ to match { // !!! TODO drop
+ case RefinedThis(rt1, -1) => RefinedThis(rt1, level)
+ case _ => to
+ }
+ else tp
case tp: NamedType =>
if (tp.currentSymbol.isStatic) tp
else tp.derivedSelect(substThis(tp.prefix, from, to, theMap))
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index 6443c5054..21aa5960e 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -409,7 +409,7 @@ class TypeApplications(val self: Type) extends AnyVal {
def replacements(rt: RefinedType): List[Type] =
for (sym <- boundSyms)
- yield TypeRef(RefinedThis(rt), correspondingParamName(sym))
+ yield TypeRef(RefinedThis(rt, 0), correspondingParamName(sym))
def rewrite(tp: Type): Type = tp match {
case tp @ RefinedType(parent, name: TypeName) =>
@@ -453,7 +453,7 @@ class TypeApplications(val self: Type) extends AnyVal {
val lambda = defn.lambdaTrait(boundSyms.map(_.variance))
val substitutedRHS = (rt: RefinedType) => {
val argRefs = boundSyms.indices.toList.map(i =>
- RefinedThis(rt).select(tpnme.lambdaArgName(i)))
+ RefinedThis(rt, 0).select(tpnme.lambdaArgName(i)))
tp.subst(boundSyms, argRefs).bounds.withVariance(1)
}
val res = RefinedType(lambda.typeRef, tpnme.Apply, substitutedRHS)
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index b8cc45fa7..85c57b744 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -309,7 +309,7 @@ class TypeComparer(initctx: Context) extends DotClass {
}
private def narrowRefined(tp: Type): Type = tp match {
- case tp: RefinedType => RefinedThis(tp)
+ case tp: RefinedType => RefinedThis(tp, 0) // !!! TODO check that we can drop narrowRefined entirely
case _ => tp
}
@@ -323,7 +323,7 @@ class TypeComparer(initctx: Context) extends DotClass {
def rebaseFrom(prefix: Type): Type = {
rebaseQual(prefix, tp.name, considerBoth = true) match {
case rt: RefinedType if rt ne prefix =>
- tp.derivedSelect(RefinedThis(rt)).dealias // dealias to short-circuit cycles spanning type aliases or LazyRefs
+ tp.derivedSelect(RefinedThis(rt, 0)).dealias // dealias to short-circuit cycles spanning type aliases or LazyRefs
case _ => tp
}
}
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index 260e2f6d6..88f495f47 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -330,7 +330,22 @@ trait TypeOps { this: Context =>
}
parentRefs
}
-
+
+ /** Map `C.this` types where `C` is `refineCls` to RefinedThis types with given level.
+ * The level gets adjusted for nested refined types.
+ */
+ def thisToRefinedThis(rt: RefinedType, refineCls: Symbol, level: Int): TypeMap = new TypeMap {
+ def apply(tp: Type): Type = tp match {
+ case tp: ThisType if tp.cls eq refineCls => RefinedThis(rt, level)
+ case tp: RefinedType =>
+ tp.derivedRefinedType(
+ this(tp.parent), tp.refinedName,
+ thisToRefinedThis(rt, refineCls, level + 1)(tp.refinedInfo))
+ case _ =>
+ mapOver(tp)
+ }
+ }
+
/** An argument bounds violation is a triple consisting of
* - the argument tree
* - a string "upper" or "lower" indicating which bound is violated
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 469e8ca01..d1b2e8f1e 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1805,7 +1805,7 @@ object Types {
&& !parent.isLambda)
derivedRefinedType(parent.EtaExpand, refinedName, refinedInfo)
else
- RefinedType(parent, refinedName, rt => refinedInfo.substThis(this, RefinedThis(rt)))
+ RefinedType(parent, refinedName, rt => refinedInfo.substThis(this, RefinedThis(rt, -1))) // !!! TODO: replace with simply `refinedInfo`
}
override def equals(that: Any) = that match {
@@ -2201,10 +2201,14 @@ object Types {
override def computeHash = doHash(paramNum, binder)
}
- case class RefinedThis(binder: RefinedType, level: Int = 0) extends BoundType with SingletonType {
+ /** A reference to the `this` of an enclosing refined type.
+ * @param level The number of enclosing refined types between
+ * the `this` reference and its target.
+ */
+ case class RefinedThis(binder: RefinedType, level: Int) extends BoundType with SingletonType {
type BT = RefinedType
override def underlying(implicit ctx: Context) = binder
- def copyBoundType(bt: BT) = RefinedThis(bt)
+ def copyBoundType(bt: BT) = RefinedThis(bt, level)
// need to customize hashCode and equals to prevent infinite recursion for
// refinements that refer to the refinement type via this
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index 728048700..2bea977f7 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -158,9 +158,6 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
/** A map from symbols to their associated `decls` scopes */
private val symScopes = mutable.AnyRefMap[Symbol, Scope]()
- /** A map from refinement classes to their associated refinement types */
- private val refinementTypes = mutable.AnyRefMap[Symbol, RefinedType]()
-
protected def errorBadSignature(msg: String, original: Option[RuntimeException] = None)(implicit ctx: Context) = {
val ex = new BadSignature(
sm"""error reading Scala signature of $classRoot from $source:
@@ -612,9 +609,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
case NOPREFIXtpe =>
NoPrefix
case THIStpe =>
- val cls = readSymbolRef().asClass
- if (isRefinementClass(cls)) RefinedThis(refinementTypes(cls))
- else cls.thisType
+ readSymbolRef().thisType
case SINGLEtpe =>
val pre = readTypeRef()
val sym = readDisambiguatedSymbolRef(_.info.isParameterless)
@@ -666,11 +661,8 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
if (decls.isEmpty) parent
else {
def addRefinement(tp: Type, sym: Symbol) =
- RefinedType(tp, sym.name, sym.info)
- val result = (parent /: decls.toList)(addRefinement).asInstanceOf[RefinedType]
- assert(!refinementTypes.isDefinedAt(clazz), clazz + "/" + decls)
- refinementTypes(clazz) = result
- result
+ RefinedType(tp, sym.name, ctx.thisToRefinedThis(_, clazz, 0)(sym.info))
+ (parent /: decls.toList)(addRefinement).asInstanceOf[RefinedType]
}
case CLASSINFOtpe =>
val clazz = readSymbolRef()
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 0ff47b36d..dd05fea3f 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -791,7 +791,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
checkRefinementNonCyclic(refinement, refineCls, seen)
val rsym = refinement.symbol
val rinfo = if (rsym is Accessor) rsym.info.resultType else rsym.info
- RefinedType(parent, rsym.name, rt => rinfo.substThis(refineCls, RefinedThis(rt)))
+ RefinedType(parent, rsym.name, ctx.thisToRefinedThis(_, refineCls, 0)(rinfo))
// todo later: check that refinement is within bounds
}
val res = cpy.RefinedTypeTree(tree)(tpt1, refinements1) withType