@@ -713,7 +713,7 @@ object Types {
713
713
/** A prefix-less termRef to a new skolem symbol that has the given type as info */
714
714
def narrow (implicit ctx : Context ): TermRef = TermRef (NoPrefix , ctx.newSkolem(this ))
715
715
716
- // ----- Normalizing typerefs over refined types ----------------------------
716
+ // ----- Normalizing typerefs over refined types ----------------------------
717
717
718
718
/** If this is a refinement type that has a refinement for `name` (which might be followed
719
719
* by other refinements), and the refined info is a type alias, return the alias,
@@ -724,58 +724,58 @@ object Types {
724
724
* to just U. Does not perform the reduction if the resulting type would contain
725
725
* a reference to the "this" of the current refined type.
726
726
*/
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 )
752
761
}
753
762
754
763
/** The type <this . name> , reduced if possible */
755
764
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
761
767
}
762
768
763
769
/** The type <this . name> , reduced if possible, with given denotation if unreduced */
764
770
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
770
773
}
771
774
772
775
/** The type <this . name> with given symbol, reduced if possible */
773
776
def select (sym : Symbol )(implicit ctx : Context ): Type =
774
777
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
779
779
780
780
// ----- Access to parts --------------------------------------------
781
781
@@ -1300,37 +1300,16 @@ 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`
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`
1304
1307
* provided `U` does not refer with a RefinedThis to the
1305
- * refinement type `T { X = U; ... }`.
1308
+ * refinement type `T { X = U; ... }`
1306
1309
*/
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
1334
1313
}
1335
1314
1336
1315
def symbol (implicit ctx : Context ): Symbol = {
0 commit comments