aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-07-22 18:43:24 +0200
committerMartin Odersky <odersky@gmail.com>2014-07-22 18:43:24 +0200
commitababb2ce2675619c997cb4bfa143b454e4076850 (patch)
treee2d22d801e06e046e2f18a51705eee5d332e1d52 /src/dotty/tools/dotc/core
parente8d2733c3e496d811bb1002418b08ba1abe3ee8b (diff)
downloaddotty-ababb2ce2675619c997cb4bfa143b454e4076850.tar.gz
dotty-ababb2ce2675619c997cb4bfa143b454e4076850.tar.bz2
dotty-ababb2ce2675619c997cb4bfa143b454e4076850.zip
Defined substitution which follows aliases
Used in FullParameterization to substitute type parameters. Fixes test failure for t2399.scala
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r--src/dotty/tools/dotc/core/Substituters.scala40
-rw-r--r--src/dotty/tools/dotc/core/Types.scala13
2 files changed, 47 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/core/Substituters.scala b/src/dotty/tools/dotc/core/Substituters.scala
index 3d14317cb..f5f60e6a5 100644
--- a/src/dotty/tools/dotc/core/Substituters.scala
+++ b/src/dotty/tools/dotc/core/Substituters.scala
@@ -89,6 +89,40 @@ trait Substituters { this: Context =>
}
}
+ final def substDealias(tp: Type, from: List[Symbol], to: List[Type], theMap: SubstDealiasMap): Type = {
+ tp match {
+ case tp: NamedType =>
+ val sym = tp.symbol
+ var fs = from
+ var ts = to
+ while (fs.nonEmpty) {
+ if (fs.head eq sym) return ts.head
+ fs = fs.tail
+ ts = ts.tail
+ }
+ if (sym.isStatic && !existsStatic(from)) tp
+ else {
+ val prefix1 = substDealias(tp.prefix, from, to, theMap)
+ if (prefix1 ne tp.prefix) tp.derivedSelect(prefix1)
+ else if (sym.isAliasType) {
+ val hi = sym.info.bounds.hi
+ val hi1 = substDealias(hi, from, to, theMap)
+ if (hi1 eq hi) tp else hi1
+ }
+ else tp
+ }
+ case _: ThisType | _: BoundType | NoPrefix =>
+ tp
+ case tp: RefinedType =>
+ tp.derivedRefinedType(substDealias(tp.parent, from, to, theMap), tp.refinedName, substDealias(tp.refinedInfo, from, to, theMap))
+ case tp: TypeBounds if tp.lo eq tp.hi =>
+ tp.derivedTypeAlias(substDealias(tp.lo, from, to, theMap))
+ case _ =>
+ (if (theMap != null) theMap else new SubstDealiasMap(from, to))
+ .mapOver(tp)
+ }
+ }
+
final def substSym(tp: Type, from: List[Symbol], to: List[Symbol], theMap: SubstSymMap): Type =
tp match {
case tp: NamedType =>
@@ -205,11 +239,11 @@ trait Substituters { this: Context =>
final class SubstMap(from: List[Symbol], to: List[Type]) extends DeepTypeMap {
def apply(tp: Type): Type = subst(tp, from, to, this)
}
-/* not needed yet
+
final class SubstDealiasMap(from: List[Symbol], to: List[Type]) extends SubstMap(from, to) {
- override def apply(tp: Type): Type = subst(tp.dealias, from, to, this)
+ override def apply(tp: Type): Type = substDealias(tp, from, to, this)
}
-*/
+
final class SubstSymMap(from: List[Symbol], to: List[Symbol]) extends DeepTypeMap {
def apply(tp: Type): Type = substSym(tp, from, to, this)
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 1d1c326a0..8149cce78 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -818,10 +818,17 @@ object Types {
}
}
-/* Not needed yet:
+ /** Same as `subst` but follows aliases as a fallback. When faced with a reference
+ * to an alias type, where normal substiution does not yield a new type, the
+ * substitution is instead applied to the alias. If that yields a new type,
+ * this type is returned, outherwise the original type (not the alias) is returned.
+ * A use case for this method is if one wants to substitute the type parameters
+ * of a class and also wants to substitute any parameter accessors that alias
+ * the type parameters.
+ */
final def substDealias(from: List[Symbol], to: List[Type])(implicit ctx: Context): Type =
- new ctx.SubstDealiasMap(from, to).apply(this)
-*/
+ ctx.substDealias(this, from, to, null)
+
/** Substitute all types of the form `PolyParam(from, N)` by
* `PolyParam(to, N)`.
*/