Skip to content

Commit 0faa252

Browse files
committed
A slightly more conservative version of #14128
Two changes - Fix `hasUpperBound` to work correctly for higher-kinded types - A more conservative fix in `IsFullyDefinedAccumulator`. We now maintain the symmetry that - if variance < 0, we maximize - if variance > 0 (and Nothing is admissible) we minimize - only if variance = 0, we use the upper bound as a tie breaker Previously, we maximized even if variance > 0 if there was an upper but no lower bound. But that was asymmetric since there is no corresponding case where we minimize at variance < 0 if there is a lower but no upper bound.
1 parent d0b2151 commit 0faa252

File tree

2 files changed

+11
-2
lines changed

2 files changed

+11
-2
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,11 @@ object Types {
251251
case _ => false
252252
}
253253

254+
/** Is this type exactly `Any`, or a type lambda ending in `Any`? */
255+
def isTopOfSomeKind(using Context): Boolean = dealias match
256+
case tp: TypeLambda => tp.resType.isTopOfSomeKind
257+
case _ => isExactlyAny
258+
254259
def isBottomType(using Context): Boolean =
255260
if ctx.mode.is(Mode.SafeNulls) && !ctx.phase.erasedTypes then hasClassSymbol(defn.NothingClass)
256261
else isBottomTypeAfterErasure
@@ -4896,7 +4901,7 @@ object Types {
48964901
def hasLowerBound(using Context): Boolean = !currentEntry.loBound.isExactlyNothing
48974902

48984903
/** For uninstantiated type variables: Is the upper bound different from Any? */
4899-
def hasUpperBound(using Context): Boolean = !currentEntry.hiBound.finalResultType.isExactlyAny
4904+
def hasUpperBound(using Context): Boolean = !currentEntry.hiBound.isTopOfSomeKind
49004905

49014906
/** Unwrap to instance (if instantiated) or origin (if not), until result
49024907
* is no longer a TypeVar

compiler/src/dotty/tools/dotc/typer/Inferencing.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,11 @@ object Inferencing {
187187
// else hold off instantiating unbounded unconstrained variable
188188
else if direction != 0 then
189189
instantiate(tvar, fromBelow = direction < 0)
190-
else if variance >= 0 && (force.ifBottom == IfBottom.ok && !tvar.hasUpperBound || tvar.hasLowerBound) then
190+
else if variance >= 0 && tvar.hasLowerBound then
191+
instantiate(tvar, fromBelow = true)
192+
else if (variance > 0 || variance == 0 && !tvar.hasUpperBound)
193+
&& force.ifBottom == IfBottom.ok
194+
then // if variance == 0, prefer upper bound if one is given
191195
instantiate(tvar, fromBelow = true)
192196
else if variance >= 0 && force.ifBottom == IfBottom.fail then
193197
fail = true

0 commit comments

Comments
 (0)