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 @@ -1300,6 +1300,39 @@ object Types {
1300
1300
if (name.isInheritedName) prefix.nonPrivateMember(name.revertInherited)
1301
1301
else prefix.member(name)
1302
1302
1303
+ /** Reduce a type-ref `T { X = U; ... } # X` to `U`
1304
+ * provided `U` does not refer with a RefinedThis to the
1305
+ * refinement type `T { X = U; ... }`.
1306
+ */
1307
+ def reduceProjection (implicit ctx : Context ) =
1308
+ if (projectsRefinement(prefix))
1309
+ info match {
1310
+ case TypeBounds (lo, hi) if (lo eq hi) && ! dependsOnRefinedThis(hi) => hi
1311
+ case _ => this
1312
+ }
1313
+ else this
1314
+
1315
+ private def projectsRefinement (tp : Type )(implicit ctx : Context ): Boolean = tp.stripTypeVar match {
1316
+ case tp : RefinedType => (tp.refinedName eq name) || projectsRefinement(tp.parent)
1317
+ case _ => false
1318
+ }
1319
+
1320
+ private def dependsOnRefinedThis (tp : Type )(implicit ctx : Context ): Boolean = tp.stripTypeVar match {
1321
+ case tp @ TypeRef (RefinedThis (rt), _) if rt refines prefix =>
1322
+ tp.info match {
1323
+ case TypeBounds (lo, hi) if lo eq hi => dependsOnRefinedThis(hi)
1324
+ case _ => true
1325
+ }
1326
+ case RefinedThis (rt) => rt refines prefix
1327
+ case tp : NamedType =>
1328
+ ! tp.symbol.isStatic && dependsOnRefinedThis(tp.prefix)
1329
+ case tp : RefinedType => dependsOnRefinedThis(tp.refinedInfo) || dependsOnRefinedThis(tp.parent)
1330
+ case tp : TypeBounds => dependsOnRefinedThis(tp.lo) || dependsOnRefinedThis(tp.hi)
1331
+ case tp : AnnotatedType => dependsOnRefinedThis(tp.underlying)
1332
+ case tp : AndOrType => dependsOnRefinedThis(tp.tp1) || dependsOnRefinedThis(tp.tp2)
1333
+ case _ => false
1334
+ }
1335
+
1303
1336
def symbol (implicit ctx : Context ): Symbol = {
1304
1337
val now = ctx.period
1305
1338
if (checkedPeriod == now ||
You can’t perform that action at this time.
0 commit comments