@@ -692,7 +692,7 @@ object Types {
692692 /** A prefix-less termRef to a new skolem symbol that has the given type as info */
693693 def narrow (implicit ctx : Context ): TermRef = TermRef (NoPrefix , ctx.newSkolem(this ))
694694
695- // ----- Normalizing typerefs over refined types ----------------------------
695+ // ----- Normalizing typerefs over refined types ----------------------------
696696
697697 /** If this is a refinement type that has a refinement for `name` (which might be followed
698698 * by other refinements), and the refined info is a type alias, return the alias,
@@ -703,58 +703,58 @@ object Types {
703703 * to just U. Does not perform the reduction if the resulting type would contain
704704 * a reference to the "this" of the current refined type.
705705 */
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 )
731740 }
732741
733742 /** The type <this . name> , reduced if possible */
734743 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
740746 }
741747
742748 /** The type <this . name> , reduced if possible, with given denotation if unreduced */
743749 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
749752 }
750753
751754 /** The type <this . name> with given symbol, reduced if possible */
752755 def select (sym : Symbol )(implicit ctx : Context ): Type =
753756 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
758758
759759// ----- Access to parts --------------------------------------------
760760
@@ -1279,37 +1279,16 @@ object Types {
12791279 if (name.isInheritedName) prefix.nonPrivateMember(name.revertInherited)
12801280 else prefix.member(name)
12811281
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`
12831286 * provided `U` does not refer with a RefinedThis to the
1284- * refinement type `T { X = U; ... }`.
1287+ * refinement type `T { X = U; ... }`
12851288 */
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
13131292 }
13141293
13151294 def symbol (implicit ctx : Context ): Symbol = {
0 commit comments