@@ -1631,17 +1631,19 @@ object Types extends TypeUtils {
1631
1631
*
1632
1632
* P { ... type T = / += / -= U ... } # T
1633
1633
*
1634
- * to just U. Does not perform the reduction if the resulting type would contain
1635
- * a reference to the "this" of the current refined type, except in the following situation
1634
+ * to just U. Analogously, `P { val x: S} # x` is reduced tp `S` is `S`
1635
+ * is a singleton type.
1636
1636
*
1637
- * (1) The "this" reference can be avoided by following an alias. Example:
1637
+ * Does not perform the reduction if the resulting type would contain
1638
+ * a reference to the "this" of the current refined type, except if the "this"
1639
+ * reference can be avoided by following an alias. Example:
1638
1640
*
1639
1641
* P { type T = String, type R = P{...}.T } # R --> String
1640
1642
*
1641
1643
* (*) normalizes means: follow instantiated typevars and aliases.
1642
1644
*/
1643
- def lookupRefined (name : Name )(using Context ): Type = {
1644
- @ tailrec def loop (pre : Type ): Type = pre.stripTypeVar match {
1645
+ def lookupRefined (name : Name )(using Context ): Type =
1646
+ @ tailrec def loop (pre : Type ): Type = pre match
1645
1647
case pre : RefinedType =>
1646
1648
pre.refinedInfo match {
1647
1649
case tp : AliasingBounds =>
@@ -1664,12 +1666,13 @@ object Types extends TypeUtils {
1664
1666
case TypeAlias (alias) => loop(alias)
1665
1667
case _ => NoType
1666
1668
}
1669
+ case pre : (TypeVar | AnnotatedType ) =>
1670
+ loop(pre.underlying)
1667
1671
case _ =>
1668
1672
NoType
1669
- }
1670
1673
1671
1674
loop(this )
1672
- }
1675
+ end lookupRefined
1673
1676
1674
1677
/** The type <this . name> , reduced if possible */
1675
1678
def select (name : Name )(using Context ): Type =
@@ -2708,13 +2711,11 @@ object Types extends TypeUtils {
2708
2711
case _ => true
2709
2712
}
2710
2713
2711
- /** Reduce a type-ref `T { X = U; ... } # X` to `U`
2712
- * provided `U` does not refer with a RecThis to the
2713
- * refinement type `T { X = U; ... }`
2714
+ /** Try to reduce this type using lookupRefined, or return the type itself
2715
+ * if that fails.
2714
2716
*/
2715
2717
def reduceProjection (using Context ): Type =
2716
- val reduced = prefix.lookupRefined(name)
2717
- if reduced.exists then reduced else this
2718
+ prefix.lookupRefined(name).orElse(this )
2718
2719
2719
2720
/** Guard against cycles that can arise if given `op`
2720
2721
* follows info. The problematic cases are a type alias to itself or
@@ -2801,35 +2802,30 @@ object Types extends TypeUtils {
2801
2802
def derivedSelect (prefix : Type )(using Context ): Type =
2802
2803
if prefix eq this .prefix then this
2803
2804
else if prefix.isExactlyNothing then prefix
2804
- else {
2805
- val res =
2806
- if ( isType && currentValidSymbol.isAllOf(ClassTypeParam )) argForParam(prefix)
2805
+ else
2806
+ val reduced =
2807
+ if isType && currentValidSymbol.isAllOf(ClassTypeParam ) then argForParam(prefix)
2807
2808
else prefix.lookupRefined(name)
2808
- if (res.exists) return res
2809
- if (isType) {
2810
- if (Config .splitProjections)
2811
- prefix match {
2812
- case prefix : AndType =>
2813
- def isMissing (tp : Type ) = tp match {
2814
- case tp : TypeRef => ! tp.info.exists
2815
- case _ => false
2816
- }
2817
- val derived1 = derivedSelect(prefix.tp1)
2818
- val derived2 = derivedSelect(prefix.tp2)
2819
- return (
2820
- if (isMissing(derived1)) derived2
2821
- else if (isMissing(derived2)) derived1
2822
- else prefix.derivedAndType(derived1, derived2))
2823
- case prefix : OrType =>
2824
- val derived1 = derivedSelect(prefix.tp1)
2825
- val derived2 = derivedSelect(prefix.tp2)
2826
- return prefix.derivedOrType(derived1, derived2)
2827
- case _ =>
2828
- }
2829
- }
2830
- if (prefix.isInstanceOf [WildcardType ]) WildcardType .sameKindAs(this )
2809
+ if reduced.exists then return reduced
2810
+ if Config .splitProjections && isType then
2811
+ prefix match
2812
+ case prefix : AndType =>
2813
+ def isMissing (tp : Type ) = tp match
2814
+ case tp : TypeRef => ! tp.info.exists
2815
+ case _ => false
2816
+ val derived1 = derivedSelect(prefix.tp1)
2817
+ val derived2 = derivedSelect(prefix.tp2)
2818
+ return
2819
+ if isMissing(derived1) then derived2
2820
+ else if isMissing(derived2) then derived1
2821
+ else prefix.derivedAndType(derived1, derived2)
2822
+ case prefix : OrType =>
2823
+ val derived1 = derivedSelect(prefix.tp1)
2824
+ val derived2 = derivedSelect(prefix.tp2)
2825
+ return prefix.derivedOrType(derived1, derived2)
2826
+ case _ =>
2827
+ if prefix.isInstanceOf [WildcardType ] then WildcardType .sameKindAs(this )
2831
2828
else withPrefix(prefix)
2832
- }
2833
2829
2834
2830
/** A reference like this one, but with the given symbol, if it exists */
2835
2831
private def withSym (sym : Symbol )(using Context ): ThisType =
0 commit comments