@@ -713,7 +713,7 @@ object Types {
713713 /** A prefix-less termRef to a new skolem symbol that has the given type as info */
714714 def narrow (implicit ctx : Context ): TermRef = TermRef (NoPrefix , ctx.newSkolem(this ))
715715
716- // ----- Normalizing typerefs over refined types ----------------------------
716+ // ----- Normalizing typerefs over refined types ----------------------------
717717
718718 /** If this is a refinement type that has a refinement for `name` (which might be followed
719719 * by other refinements), and the refined info is a type alias, return the alias,
@@ -724,58 +724,58 @@ object Types {
724724 * to just U. Does not perform the reduction if the resulting type would contain
725725 * a reference to the "this" of the current refined type.
726726 */
727- def lookupRefined (name : Name )(implicit ctx : Context ): Type = stripTypeVar match {
728- case pre : RefinedType =>
729- def dependsOnThis (tp : Type ): Boolean = tp match {
730- case tp @ TypeRef (RefinedThis (rt), _) if rt refines pre =>
731- tp.info match {
732- case TypeBounds (lo, hi) if lo eq hi => dependsOnThis(hi)
733- case _ => true
734- }
735- case RefinedThis (rt) =>
736- rt refines pre
737- case _ => false
738- }
739- if (pre.refinedName ne name)
740- pre.parent.lookupRefined(name)
741- else pre.refinedInfo match {
742- case TypeBounds (lo, hi) if lo eq hi =>
743- if (hi.existsPart(dependsOnThis)) NoType else hi
744- case _ => NoType
745- }
746- case RefinedThis (rt) =>
747- rt.lookupRefined(name)
748- case pre : WildcardType =>
749- WildcardType
750- case _ =>
751- NoType
727+ def lookupRefined (name : Name )(implicit ctx : Context ): Type = {
728+
729+ def dependsOnRefinedThis (tp : Type ): Boolean = tp.stripTypeVar match {
730+ case tp @ TypeRef (RefinedThis (rt), _) if rt refines this =>
731+ tp.info match {
732+ case TypeBounds (lo, hi) if lo eq hi => dependsOnRefinedThis(hi)
733+ case _ => true
734+ }
735+ case RefinedThis (rt) => rt refines this
736+ case tp : NamedType =>
737+ ! tp.symbol.isStatic && dependsOnRefinedThis(tp.prefix)
738+ case tp : RefinedType => dependsOnRefinedThis(tp.refinedInfo) || dependsOnRefinedThis(tp.parent)
739+ case tp : TypeBounds => dependsOnRefinedThis(tp.lo) || dependsOnRefinedThis(tp.hi)
740+ case tp : AnnotatedType => dependsOnRefinedThis(tp.underlying)
741+ case tp : AndOrType => dependsOnRefinedThis(tp.tp1) || dependsOnRefinedThis(tp.tp2)
742+ case _ => false
743+ }
744+
745+ def loop (pre : Type ): Type = pre.stripTypeVar match {
746+ case pre : RefinedType =>
747+ if (pre.refinedName ne name) loop(pre.parent)
748+ else this .member(name).info match {
749+ case TypeBounds (lo, hi) if (lo eq hi) && ! dependsOnRefinedThis(hi) => hi
750+ case _ => NoType
751+ }
752+ case RefinedThis (rt) =>
753+ rt.lookupRefined(name)
754+ case pre : WildcardType =>
755+ WildcardType
756+ case _ =>
757+ NoType
758+ }
759+
760+ loop(this )
752761 }
753762
754763 /** The type <this . name> , reduced if possible */
755764 def select (name : Name )(implicit ctx : Context ): Type = name match {
756- case name : TermName =>
757- TermRef .all(this , name)
758- case name : TypeName =>
759- val res = lookupRefined(name)
760- if (res.exists) res else TypeRef (this , name)
765+ case name : TermName => TermRef .all(this , name)
766+ case name : TypeName => TypeRef (this , name).reduceProjection
761767 }
762768
763769 /** The type <this . name> , reduced if possible, with given denotation if unreduced */
764770 def select (name : Name , denot : Denotation )(implicit ctx : Context ): Type = name match {
765- case name : TermName =>
766- TermRef (this , name, denot)
767- case name : TypeName =>
768- val res = lookupRefined(name)
769- if (res.exists) res else TypeRef (this , name, denot)
771+ case name : TermName => TermRef (this , name, denot)
772+ case name : TypeName => TypeRef (this , name, denot).reduceProjection
770773 }
771774
772775 /** The type <this . name> with given symbol, reduced if possible */
773776 def select (sym : Symbol )(implicit ctx : Context ): Type =
774777 if (sym.isTerm) TermRef (this , sym.asTerm)
775- else {
776- val res = lookupRefined(sym.name)
777- if (res.exists) res else TypeRef (this , sym.asType)
778- }
778+ else TypeRef (this , sym.asType).reduceProjection
779779
780780// ----- Access to parts --------------------------------------------
781781
@@ -1300,37 +1300,16 @@ object Types {
13001300 if (name.isInheritedName) prefix.nonPrivateMember(name.revertInherited)
13011301 else prefix.member(name)
13021302
1303- /** Reduce a type-ref `T { X = U; ... } # X` to `U`
1303+ /** (1) Reduce a type-ref `W # X` or `W { ... } # U`, where `W` is a wildcard type
1304+ * to an (unbounded) wildcard type.
1305+ *
1306+ * (2) Reduce a type-ref `T { X = U; ... } # X` to `U`
13041307 * provided `U` does not refer with a RefinedThis to the
1305- * refinement type `T { X = U; ... }`.
1308+ * refinement type `T { X = U; ... }`
13061309 */
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
1310+ def reduceProjection (implicit ctx : Context ): Type = {
1311+ val reduced = prefix.lookupRefined(name)
1312+ if (reduced.exists) reduced else this
13341313 }
13351314
13361315 def symbol (implicit ctx : Context ): Symbol = {
0 commit comments