Skip to content

Commit 36d9c26

Browse files
committed
Cleanup addOneBound logic
1 parent 7b4fd8b commit 36d9c26

File tree

1 file changed

+23
-23
lines changed

1 file changed

+23
-23
lines changed

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

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -79,42 +79,42 @@ trait ConstraintHandling {
7979
def fullBounds(param: TypeParamRef)(using Context): TypeBounds =
8080
nonParamBounds(param).derivedTypeBounds(fullLowerBound(param), fullUpperBound(param))
8181

82-
protected def allowWildcards: Boolean = true
82+
/** If true: eliminate wildcards in bounds by avoidance.
83+
* Otherwise replace them by fresh variables, except that
84+
* in mode TypeVarsMissContext, wildcards are always eliminated by approximation.
85+
*/
86+
protected def approximateWildcards: Boolean = true
8387

84-
protected def addOneBound(param: TypeParamRef, bound: Type, isUpper: Boolean)(using Context): Boolean =
88+
protected def addOneBound(param: TypeParamRef, bound0: Type, isUpper: Boolean)(using Context): Boolean =
8589
if !constraint.contains(param) then true
86-
else if !isUpper && param.occursIn(bound) then
90+
else if !isUpper && param.occursIn(bound0) then
8791
// We don't allow recursive lower bounds when defining a type,
8892
// so we shouldn't allow them as constraints either.
8993
false
9094
else
95+
val dropWildcards = new ApproximatingTypeMap:
96+
if !isUpper then variance = -1
97+
def apply(t: Type): Type = t match
98+
case t: WildcardType =>
99+
if approximateWildcards || ctx.mode.is(Mode.TypevarsMissContext) then
100+
val bounds = t.effectiveBounds
101+
range(bounds.lo, bounds.hi)
102+
else
103+
newTypeVar(t.effectiveBounds)
104+
case _ =>
105+
mapOver(t)
106+
val bound1 = dropWildcards(bound0)
91107
val oldBounds @ TypeBounds(lo, hi) = constraint.nonParamBounds(param)
92-
val equalBounds = (if isUpper then lo else hi) eq bound
93-
if equalBounds
94-
&& !bound.existsPart(bp => bp.isInstanceOf[WildcardType] || (bp eq param))
95-
then
96-
// The narrowed bounds are equal and do not contain wildcards,
108+
val equalBounds = (if isUpper then lo else hi) eq bound1
109+
if equalBounds && !bound1.existsPart(_ eq param, stopAtStatic = true) then
110+
// The narrowed bounds are equal and not recursive,
97111
// so we can remove `param` from the constraint.
98-
// (Handling wildcards requires choosing a bound, but we don't know which
99-
// bound to choose here, this is handled in `ConstraintHandling#approximation`)
100-
constraint = constraint.replace(param, bound)
112+
constraint = constraint.replace(param, bound1)
101113
true
102114
else
103-
val dropWildcards = new ApproximatingTypeMap:
104-
if !isUpper then variance = -1
105-
def apply(t: Type): Type = t match
106-
case t: WildcardType =>
107-
if !allowWildcards || ctx.mode.is(Mode.TypevarsMissContext) then
108-
val bounds = t.effectiveBounds
109-
range(bounds.lo, bounds.hi)
110-
else
111-
newTypeVar(t.effectiveBounds)
112-
case _ =>
113-
mapOver(t)
114115
// Narrow one of the bounds of type parameter `param`
115116
// If `isUpper` is true, ensure that `param <: `bound`, otherwise ensure
116117
// that `param >: bound`.
117-
val bound1 = dropWildcards(bound)
118118
val narrowedBounds =
119119
val saved = homogenizeArgs
120120
homogenizeArgs = Config.alignArgsInAnd

0 commit comments

Comments
 (0)