Skip to content

Commit 22be802

Browse files
committed
GADT: move dropping GADT symbols into foldLeft
1 parent 715bca8 commit 22be802

File tree

1 file changed

+21
-30
lines changed

1 file changed

+21
-30
lines changed

compiler/src/dotty/tools/dotc/core/GadtConstraint.scala

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package dotc
33
package core
44

55
import Contexts.*, Decorators.*, Symbols.*, Types.*
6+
import NameKinds.UniqueName
67
import config.Printers.{gadts, gadtsConstr}
78
import util.{SimpleIdentitySet, SimpleIdentityMap}
89
import 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

Comments
 (0)