@@ -692,7 +692,7 @@ object Types {
692
692
/** A prefix-less termRef to a new skolem symbol that has the given type as info */
693
693
def narrow (implicit ctx : Context ): TermRef = TermRef (NoPrefix , ctx.newSkolem(this ))
694
694
695
- // ----- Normalizing typerefs over refined types ----------------------------
695
+ // ----- Normalizing typerefs over refined types ----------------------------
696
696
697
697
/** If this is a refinement type that has a refinement for `name` (which might be followed
698
698
* by other refinements), and the refined info is a type alias, return the alias,
@@ -703,58 +703,58 @@ object Types {
703
703
* to just U. Does not perform the reduction if the resulting type would contain
704
704
* a reference to the "this" of the current refined type.
705
705
*/
706
- def lookupRefined (name : Name )(implicit ctx : Context ): Type = stripTypeVar match {
707
- case pre : RefinedType =>
708
- def dependsOnThis (tp : Type ): Boolean = tp match {
709
- case tp @ TypeRef (RefinedThis (rt), _) if rt refines pre =>
710
- tp.info match {
711
- case TypeBounds (lo, hi) if lo eq hi => dependsOnThis(hi)
712
- case _ => true
713
- }
714
- case RefinedThis (rt) =>
715
- rt refines pre
716
- case _ => false
717
- }
718
- if (pre.refinedName ne name)
719
- pre.parent.lookupRefined(name)
720
- else pre.refinedInfo match {
721
- case TypeBounds (lo, hi) if lo eq hi =>
722
- if (hi.existsPart(dependsOnThis)) NoType else hi
723
- case _ => NoType
724
- }
725
- case RefinedThis (rt) =>
726
- rt.lookupRefined(name)
727
- case pre : WildcardType =>
728
- WildcardType
729
- case _ =>
730
- NoType
706
+ def lookupRefined (name : Name )(implicit ctx : Context ): Type = {
707
+
708
+ def dependsOnRefinedThis (tp : Type ): Boolean = tp.stripTypeVar match {
709
+ case tp @ TypeRef (RefinedThis (rt), _) if rt refines this =>
710
+ tp.info match {
711
+ case TypeBounds (lo, hi) if lo eq hi => dependsOnRefinedThis(hi)
712
+ case _ => true
713
+ }
714
+ case RefinedThis (rt) => rt refines this
715
+ case tp : NamedType =>
716
+ ! tp.symbol.isStatic && dependsOnRefinedThis(tp.prefix)
717
+ case tp : RefinedType => dependsOnRefinedThis(tp.refinedInfo) || dependsOnRefinedThis(tp.parent)
718
+ case tp : TypeBounds => dependsOnRefinedThis(tp.lo) || dependsOnRefinedThis(tp.hi)
719
+ case tp : AnnotatedType => dependsOnRefinedThis(tp.underlying)
720
+ case tp : AndOrType => dependsOnRefinedThis(tp.tp1) || dependsOnRefinedThis(tp.tp2)
721
+ case _ => false
722
+ }
723
+
724
+ def loop (pre : Type ): Type = pre.stripTypeVar match {
725
+ case pre : RefinedType =>
726
+ if (pre.refinedName ne name) loop(pre.parent)
727
+ else this .member(name).info match {
728
+ case TypeBounds (lo, hi) if (lo eq hi) && ! dependsOnRefinedThis(hi) => hi
729
+ case _ => NoType
730
+ }
731
+ case RefinedThis (rt) =>
732
+ rt.lookupRefined(name)
733
+ case pre : WildcardType =>
734
+ WildcardType
735
+ case _ =>
736
+ NoType
737
+ }
738
+
739
+ loop(this )
731
740
}
732
741
733
742
/** The type <this . name> , reduced if possible */
734
743
def select (name : Name )(implicit ctx : Context ): Type = name match {
735
- case name : TermName =>
736
- TermRef .all(this , name)
737
- case name : TypeName =>
738
- val res = lookupRefined(name)
739
- if (res.exists) res else TypeRef (this , name)
744
+ case name : TermName => TermRef .all(this , name)
745
+ case name : TypeName => TypeRef (this , name).reduceProjection
740
746
}
741
747
742
748
/** The type <this . name> , reduced if possible, with given denotation if unreduced */
743
749
def select (name : Name , denot : Denotation )(implicit ctx : Context ): Type = name match {
744
- case name : TermName =>
745
- TermRef (this , name, denot)
746
- case name : TypeName =>
747
- val res = lookupRefined(name)
748
- if (res.exists) res else TypeRef (this , name, denot)
750
+ case name : TermName => TermRef (this , name, denot)
751
+ case name : TypeName => TypeRef (this , name, denot).reduceProjection
749
752
}
750
753
751
754
/** The type <this . name> with given symbol, reduced if possible */
752
755
def select (sym : Symbol )(implicit ctx : Context ): Type =
753
756
if (sym.isTerm) TermRef (this , sym.asTerm)
754
- else {
755
- val res = lookupRefined(sym.name)
756
- if (res.exists) res else TypeRef (this , sym.asType)
757
- }
757
+ else TypeRef (this , sym.asType).reduceProjection
758
758
759
759
// ----- Access to parts --------------------------------------------
760
760
@@ -1279,37 +1279,16 @@ 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`
1282
+ /** (1) Reduce a type-ref `W # X` or `W { ... } # U`, where `W` is a wildcard type
1283
+ * to an (unbounded) wildcard type.
1284
+ *
1285
+ * (2) Reduce a type-ref `T { X = U; ... } # X` to `U`
1283
1286
* provided `U` does not refer with a RefinedThis to the
1284
- * refinement type `T { X = U; ... }`.
1287
+ * refinement type `T { X = U; ... }`
1285
1288
*/
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
1289
+ def reduceProjection (implicit ctx : Context ): Type = {
1290
+ val reduced = prefix.lookupRefined(name)
1291
+ if (reduced.exists) reduced else this
1313
1292
}
1314
1293
1315
1294
def symbol (implicit ctx : Context ): Symbol = {
0 commit comments