Skip to content

Commit 42d35a6

Browse files
committed
Replace TypeArgRefs by normal TypeRefs
This commit avoids replaces a TypeArgRef by a normal reference to a type parameter.
1 parent 4f1227e commit 42d35a6

File tree

4 files changed

+58
-4
lines changed

4 files changed

+58
-4
lines changed

compiler/src/dotty/tools/dotc/config/Config.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,4 +179,6 @@ object Config {
179179

180180
/** When in IDE, turn StaleSymbol errors into warnings instead of crashing */
181181
final val ignoreStaleInIDE = true
182+
183+
val newScheme = true
182184
}

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,9 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
829829

830830
def compareCaptured(arg1: Type, arg2: Type): Boolean = arg1 match {
831831
case arg1: TypeBounds =>
832-
val captured = TypeArgRef.fromParam(tp1, tparam.asInstanceOf[TypeSymbol])
832+
val captured =
833+
if (Config.newScheme) TypeRef(tp1, tparam.asInstanceOf[TypeSymbol])
834+
else TypeArgRef.fromParam(tp1, tparam.asInstanceOf[TypeSymbol])
833835
isSubArg(captured, arg2)
834836
case _ =>
835837
false

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

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,18 @@ object Types {
182182
loop(this)
183183
}
184184

185+
/** True iff `symd` is a denotation of a class type parameter and the reference
186+
* `<this> . <symd>` is an actual argument reference, i.e. `this` is different
187+
* from the ThisType of `symd`'s owner.
188+
*/
189+
def isArgPrefix(symd: SymDenotation)(implicit ctx: Context) =
190+
Config.newScheme && symd.is(ClassTypeParam) && {
191+
this match {
192+
case tp: ThisType => tp.cls ne symd.owner
193+
case _ => true
194+
}
195+
}
196+
185197
/** Returns true if the type is a phantom type
186198
* - true if XYZ extends scala.Phantom and this type is upper bounded XYZ.Any
187199
* - false otherwise
@@ -1653,6 +1665,8 @@ object Types {
16531665
val symd = sym.lastKnownDenotation
16541666
if (symd.validFor.runId != ctx.runId && !ctx.stillValid(symd))
16551667
finish(memberDenot(symd.initial.name, allowPrivate = false))
1668+
else if (prefix.isArgPrefix(symd))
1669+
finish(argDenot(sym.asType))
16561670
else if (infoDependsOnPrefix(symd, prefix))
16571671
finish(memberDenot(symd.initial.name, allowPrivate = symd.is(Private)))
16581672
else
@@ -1708,6 +1722,32 @@ object Types {
17081722
private def memberDenot(prefix: Type, name: Name, allowPrivate: Boolean)(implicit ctx: Context): Denotation =
17091723
if (allowPrivate) prefix.member(name) else prefix.nonPrivateMember(name)
17101724

1725+
private def argDenot(param: TypeSymbol)(implicit ctx: Context): Denotation = {
1726+
val cls = param.owner
1727+
val args = prefix.baseType(cls).argInfos
1728+
val typeParams = cls.typeParams
1729+
1730+
def concretize(arg: Type, tparam: TypeSymbol) = arg match {
1731+
case arg: TypeBounds => TypeRef(prefix, tparam)
1732+
case arg => arg
1733+
}
1734+
val concretized = args.zipWithConserve(typeParams)(concretize)
1735+
1736+
def rebase(arg: Type) = arg.subst(typeParams, concretized)
1737+
1738+
val idx = typeParams.indexOf(param)
1739+
val argInfo = args(idx) match {
1740+
case arg: TypeBounds =>
1741+
val v = param.paramVariance
1742+
val pbounds = param.paramInfo
1743+
if (v > 0 && pbounds.loBound.dealias.isBottomType) TypeAlias(arg.hiBound & rebase(pbounds.hiBound))
1744+
else if (v < 0 && pbounds.hiBound.dealias.isTopType) TypeAlias(arg.loBound | rebase(pbounds.loBound))
1745+
else arg recoverable_& rebase(pbounds)
1746+
case arg => TypeAlias(arg)
1747+
}
1748+
param.derivedSingleDenotation(param, argInfo)
1749+
}
1750+
17111751
/** Reload denotation by computing the member with the reference's name as seen
17121752
* from the reference's prefix.
17131753
*/
@@ -1831,7 +1871,9 @@ object Types {
18311871
while (tparams.nonEmpty && args.nonEmpty) {
18321872
if (tparams.head.eq(tparam))
18331873
return args.head match {
1834-
case _: TypeBounds => TypeArgRef(pre, cls.typeRef, idx)
1874+
case _: TypeBounds =>
1875+
if (Config.newScheme) TypeRef(pre, tparam)
1876+
else TypeArgRef(pre, cls.typeRef, idx)
18351877
case arg => arg
18361878
}
18371879
tparams = tparams.tail
@@ -1930,7 +1972,7 @@ object Types {
19301972
else if (lastDenotation == null) NamedType(prefix, designator)
19311973
else designator match {
19321974
case sym: Symbol =>
1933-
if (infoDependsOnPrefix(sym, prefix)) {
1975+
if (infoDependsOnPrefix(sym, prefix) && !prefix.isArgPrefix(sym)) {
19341976
val candidate = reload()
19351977
val falseOverride = sym.isClass && candidate.symbol.exists && candidate.symbol != symbol
19361978
// A false override happens if we rebind an inner class to another type with the same name
@@ -4007,6 +4049,11 @@ object Types {
40074049
case TypeBounds(lo, hi) => range(atVariance(-variance)(reapply(lo)), reapply(hi))
40084050
case arg => reapply(arg)
40094051
}
4052+
case arg @ TypeRef(pre, _) if pre.isArgPrefix(arg.symbol) =>
4053+
arg.info match {
4054+
case TypeBounds(lo, hi) => range(atVariance(-variance)(reapply(lo)), reapply(hi))
4055+
case arg => reapply(arg)
4056+
}
40104057
case arg => reapply(arg)
40114058
}
40124059
}

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,10 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
235235
val name = readName().toTypeName
236236
val prefix = readType()
237237
val space = readType()
238-
TypeRef(prefix, name, space.decl(name))
238+
space.decl(name) match {
239+
case symd: SymDenotation if prefix.isArgPrefix(symd.symbol) => TypeRef(prefix, symd.symbol)
240+
case _ => TypeRef(prefix, name, space.decl(name))
241+
}
239242
case REFINEDtype =>
240243
var name: Name = readName()
241244
val parent = readType()

0 commit comments

Comments
 (0)