@@ -3,6 +3,7 @@ package dotc
3
3
package core
4
4
5
5
import Contexts .* , Decorators .* , Symbols .* , Types .*
6
+ import NameKinds .UniqueName
6
7
import config .Printers .{gadts , gadtsConstr }
7
8
import util .{SimpleIdentitySet , SimpleIdentityMap }
8
9
import printing ._
@@ -72,36 +73,30 @@ class GadtConstraint private (
72
73
73
74
def fullLowerBound (param : TypeParamRef )(using Context ): Type =
74
75
val self = externalize(param)
75
- constraint.minLower(param).filterNot { p =>
76
- val sym = paramSymbol(p)
77
- sym.name.is(NameKinds .UniqueName ) && {
78
- val hi = sym.info.hiBound
79
- ! hi.isExactlyAny && self <:< hi
80
- // drop any lower param that is a GADT symbol
81
- // and is upper-bounded by a non-Any super-type of the original parameter
82
- // e.g. in pos/i14287.min
83
- // B$1 had info <: X and fullBounds >: B$2 <: X, and
84
- // B$2 had info <: B$1 and fullBounds <: B$1
85
- // We can use the info of B$2 to drop the lower-bound of B$1
86
- // and return non-bidirectional bounds B$1 <: X and B$2 <: B$1.
87
- }
88
- }.foldLeft(nonParamBounds(param).lo) {
89
- (t, u) => t | externalize(u)
76
+ constraint.minLower(param).foldLeft(nonParamBounds(param).lo) { (acc, p) =>
77
+ externalize(p) match
78
+ case tp : TypeRef
79
+ // drop any lower param that is a GADT symbol
80
+ // and is upper-bounded by a non-Any super-type of the original parameter
81
+ // e.g. in pos/i14287.min
82
+ // B$1 had info <: X and fullBounds >: B$2 <: X, and
83
+ // B$2 had info <: B$1 and fullBounds <: B$1
84
+ // We can use the info of B$2 to drop the lower-bound of B$1
85
+ // and return non-bidirectional bounds B$1 <: X and B$2 <: B$1.
86
+ if tp.name.is(UniqueName ) && ! tp.info.hiBound.isExactlyAny && self <:< tp.info.hiBound => acc
87
+ case tp => acc | tp
90
88
}
91
89
92
90
def fullUpperBound (param : TypeParamRef )(using Context ): Type =
93
91
val self = externalize(param)
94
- constraint.minUpper(param).filterNot { p =>
95
- val sym = paramSymbol(p)
96
- sym.name.is(NameKinds .UniqueName ) && {
97
- val lo = sym.info.loBound
98
- ! lo.isExactlyNothing && lo <:< self // same as fullLowerBounds
99
- }
100
- }.foldLeft(nonParamBounds(param).hi) { (t, u) =>
101
- val eu = externalize(u)
102
- // Any as the upper bound means "no bound", but if F is higher-kinded,
103
- // Any & F = F[_]; this is wrong for us so we need to short-circuit
104
- if t.isAny then eu else t & eu
92
+ constraint.minUpper(param).foldLeft(nonParamBounds(param).hi) { (acc, u) =>
93
+ externalize(u) match
94
+ case tp : TypeRef // same as fullLowerBounds
95
+ if tp.name.is(UniqueName ) && ! tp.info.loBound.isExactlyNothing && tp.info.loBound <:< self => acc
96
+ case tp =>
97
+ // Any as the upper bound means "no bound", but if F is higher-kinded,
98
+ // Any & F = F[_]; this is wrong for us so we need to short-circuit
99
+ if acc.isAny then tp else acc & tp
105
100
}
106
101
107
102
def externalize (tp : Type , theMap : TypeMap | Null = null )(using Context ): Type = tp match
@@ -117,10 +112,6 @@ class GadtConstraint private (
117
112
def tvarOrError (sym : Symbol )(using Context ): TypeVar =
118
113
mapping(sym).ensuring(_ != null , i " not a constrainable symbol: $sym" ).uncheckedNN
119
114
120
- private def paramSymbol (p : TypeParamRef ): Symbol = reverseMapping(p) match
121
- case sym : Symbol => sym
122
- case null => NoSymbol
123
-
124
115
@ tailrec final def stripInternalTypeVar (tp : Type ): Type = tp match
125
116
case tv : TypeVar =>
126
117
val inst = constraint.instType(tv)
0 commit comments