Skip to content

Commit ababb2c

Browse files
committed
Defined substitution which follows aliases
Used in FullParameterization to substitute type parameters. Fixes test failure for t2399.scala
1 parent e8d2733 commit ababb2c

File tree

3 files changed

+49
-8
lines changed

3 files changed

+49
-8
lines changed

src/dotty/tools/dotc/core/Substituters.scala

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,40 @@ trait Substituters { this: Context =>
8989
}
9090
}
9191

92+
final def substDealias(tp: Type, from: List[Symbol], to: List[Type], theMap: SubstDealiasMap): Type = {
93+
tp match {
94+
case tp: NamedType =>
95+
val sym = tp.symbol
96+
var fs = from
97+
var ts = to
98+
while (fs.nonEmpty) {
99+
if (fs.head eq sym) return ts.head
100+
fs = fs.tail
101+
ts = ts.tail
102+
}
103+
if (sym.isStatic && !existsStatic(from)) tp
104+
else {
105+
val prefix1 = substDealias(tp.prefix, from, to, theMap)
106+
if (prefix1 ne tp.prefix) tp.derivedSelect(prefix1)
107+
else if (sym.isAliasType) {
108+
val hi = sym.info.bounds.hi
109+
val hi1 = substDealias(hi, from, to, theMap)
110+
if (hi1 eq hi) tp else hi1
111+
}
112+
else tp
113+
}
114+
case _: ThisType | _: BoundType | NoPrefix =>
115+
tp
116+
case tp: RefinedType =>
117+
tp.derivedRefinedType(substDealias(tp.parent, from, to, theMap), tp.refinedName, substDealias(tp.refinedInfo, from, to, theMap))
118+
case tp: TypeBounds if tp.lo eq tp.hi =>
119+
tp.derivedTypeAlias(substDealias(tp.lo, from, to, theMap))
120+
case _ =>
121+
(if (theMap != null) theMap else new SubstDealiasMap(from, to))
122+
.mapOver(tp)
123+
}
124+
}
125+
92126
final def substSym(tp: Type, from: List[Symbol], to: List[Symbol], theMap: SubstSymMap): Type =
93127
tp match {
94128
case tp: NamedType =>
@@ -205,11 +239,11 @@ trait Substituters { this: Context =>
205239
final class SubstMap(from: List[Symbol], to: List[Type]) extends DeepTypeMap {
206240
def apply(tp: Type): Type = subst(tp, from, to, this)
207241
}
208-
/* not needed yet
242+
209243
final class SubstDealiasMap(from: List[Symbol], to: List[Type]) extends SubstMap(from, to) {
210-
override def apply(tp: Type): Type = subst(tp.dealias, from, to, this)
244+
override def apply(tp: Type): Type = substDealias(tp, from, to, this)
211245
}
212-
*/
246+
213247
final class SubstSymMap(from: List[Symbol], to: List[Symbol]) extends DeepTypeMap {
214248
def apply(tp: Type): Type = substSym(tp, from, to, this)
215249
}

src/dotty/tools/dotc/core/Types.scala

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -818,10 +818,17 @@ object Types {
818818
}
819819
}
820820

821-
/* Not needed yet:
821+
/** Same as `subst` but follows aliases as a fallback. When faced with a reference
822+
* to an alias type, where normal substiution does not yield a new type, the
823+
* substitution is instead applied to the alias. If that yields a new type,
824+
* this type is returned, outherwise the original type (not the alias) is returned.
825+
* A use case for this method is if one wants to substitute the type parameters
826+
* of a class and also wants to substitute any parameter accessors that alias
827+
* the type parameters.
828+
*/
822829
final def substDealias(from: List[Symbol], to: List[Type])(implicit ctx: Context): Type =
823-
new ctx.SubstDealiasMap(from, to).apply(this)
824-
*/
830+
ctx.substDealias(this, from, to, null)
831+
825832
/** Substitute all types of the form `PolyParam(from, N)` by
826833
* `PolyParam(to, N)`.
827834
*/

src/dotty/tools/dotc/transform/FullParameterization.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ trait FullParameterization {
104104
/** Replace class type parameters by the added type parameters of the polytype `pt` */
105105
def mapClassParams(tp: Type, pt: PolyType): Type = {
106106
val classParamsRange = (mtparamCount until mtparamCount + ctparams.length).toList
107-
tp.subst(clazz.typeParams, classParamsRange map (PolyParam(pt, _)))
107+
tp.substDealias(clazz.typeParams, classParamsRange map (PolyParam(pt, _)))
108108
}
109109

110110
/** The bounds for the added type paraneters of the polytype `pt` */
@@ -201,7 +201,7 @@ trait FullParameterization {
201201

202202
new TreeTypeMap(
203203
typeMap = rewireType(_)
204-
.subst(origTParams, trefs)
204+
.substDealias(origTParams, trefs)
205205
.subst(origVParams, argRefs.map(_.tpe))
206206
.substThisUnlessStatic(origClass, thisRef.tpe),
207207
ownerMap = (sym => if (sym eq origMeth) derived else sym),

0 commit comments

Comments
 (0)