File tree 2 files changed +40
-1
lines changed
src/dotty/tools/dotc/core
2 files changed +40
-1
lines changed Original file line number Diff line number Diff line change @@ -56,7 +56,13 @@ trait TypeOps { this: Context =>
56
56
final def simplify (tp : Type , theMap : SimplifyMap ): Type = tp match {
57
57
case tp : NamedType =>
58
58
if (tp.symbol.isStatic) tp
59
- else tp.derivedSelect(simplify(tp.prefix, theMap))
59
+ else tp.derivedSelect(simplify(tp.prefix, theMap)) match {
60
+ case tp1 : NamedType if tp1.denotationIsCurrent =>
61
+ val tp2 = tp1.reduceProjection
62
+ // if (tp2 ne tp1) println(i"simplified $tp1 -> $tp2")
63
+ tp2
64
+ case tp1 => tp1
65
+ }
60
66
case tp : PolyParam =>
61
67
typerState.constraint.typeVarOfParam(tp) orElse tp
62
68
case _ : ThisType | _ : BoundType | NoPrefix =>
Original file line number Diff line number Diff line change @@ -1279,6 +1279,39 @@ object Types {
1279
1279
if (name.isInheritedName) prefix.nonPrivateMember(name.revertInherited)
1280
1280
else prefix.member(name)
1281
1281
1282
+ /** Reduce a type-ref `T { X = U; ... } # X` to `U`
1283
+ * provided `U` does not refer with a RefinedThis to the
1284
+ * refinement type `T { X = U; ... }`.
1285
+ */
1286
+ def reduceProjection (implicit ctx : Context ) =
1287
+ if (projectsRefinement(prefix))
1288
+ info match {
1289
+ case TypeBounds (lo, hi) if (lo eq hi) && ! dependsOnRefinedThis(hi) => hi
1290
+ case _ => this
1291
+ }
1292
+ else this
1293
+
1294
+ private def projectsRefinement (tp : Type )(implicit ctx : Context ): Boolean = tp.stripTypeVar match {
1295
+ case tp : RefinedType => (tp.refinedName eq name) || projectsRefinement(tp.parent)
1296
+ case _ => false
1297
+ }
1298
+
1299
+ private def dependsOnRefinedThis (tp : Type )(implicit ctx : Context ): Boolean = tp.stripTypeVar match {
1300
+ case tp @ TypeRef (RefinedThis (rt), _) if rt refines prefix =>
1301
+ tp.info match {
1302
+ case TypeBounds (lo, hi) if lo eq hi => dependsOnRefinedThis(hi)
1303
+ case _ => true
1304
+ }
1305
+ case RefinedThis (rt) => rt refines prefix
1306
+ case tp : NamedType =>
1307
+ ! tp.symbol.isStatic && dependsOnRefinedThis(tp.prefix)
1308
+ case tp : RefinedType => dependsOnRefinedThis(tp.refinedInfo) || dependsOnRefinedThis(tp.parent)
1309
+ case tp : TypeBounds => dependsOnRefinedThis(tp.lo) || dependsOnRefinedThis(tp.hi)
1310
+ case tp : AnnotatedType => dependsOnRefinedThis(tp.underlying)
1311
+ case tp : AndOrType => dependsOnRefinedThis(tp.tp1) || dependsOnRefinedThis(tp.tp2)
1312
+ case _ => false
1313
+ }
1314
+
1282
1315
def symbol (implicit ctx : Context ): Symbol = {
1283
1316
val now = ctx.period
1284
1317
if (checkedPeriod == now ||
You can’t perform that action at this time.
0 commit comments