@@ -3,6 +3,7 @@ package dotc
33package core
44
55import Contexts .* , Decorators .* , Symbols .* , Types .*
6+ import NameKinds .UniqueName
67import config .Printers .{gadts , gadtsConstr }
78import util .{SimpleIdentitySet , SimpleIdentityMap }
89import printing ._
@@ -72,36 +73,30 @@ class GadtConstraint private (
7273
7374 def fullLowerBound (param : TypeParamRef )(using Context ): Type =
7475 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
9088 }
9189
9290 def fullUpperBound (param : TypeParamRef )(using Context ): Type =
9391 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
105100 }
106101
107102 def externalize (tp : Type , theMap : TypeMap | Null = null )(using Context ): Type = tp match
@@ -117,10 +112,6 @@ class GadtConstraint private (
117112 def tvarOrError (sym : Symbol )(using Context ): TypeVar =
118113 mapping(sym).ensuring(_ != null , i " not a constrainable symbol: $sym" ).uncheckedNN
119114
120- private def paramSymbol (p : TypeParamRef ): Symbol = reverseMapping(p) match
121- case sym : Symbol => sym
122- case null => NoSymbol
123-
124115 @ tailrec final def stripInternalTypeVar (tp : Type ): Type = tp match
125116 case tv : TypeVar =>
126117 val inst = constraint.instType(tv)
0 commit comments