Skip to content

Commit e2b212d

Browse files
committed
Only drop wildcards for necesessary comparisons
Wildcards in constraints essentially mean that the constrained variable is a sub/supertype of _every_ instance of the bound. For useNecesaryEither, this is wrong. Approximate the bound not to use wildcards instead.
1 parent c3f5851 commit e2b212d

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ trait ConstraintHandling {
7878
def fullBounds(param: TypeParamRef)(using Context): TypeBounds =
7979
nonParamBounds(param).derivedTypeBounds(fullLowerBound(param), fullUpperBound(param))
8080

81+
protected def allowWildcards: Boolean = true
82+
8183
protected def addOneBound(param: TypeParamRef, bound: Type, isUpper: Boolean)(using Context): Boolean =
8284
if !constraint.contains(param) then true
8385
else if !isUpper && param.occursIn(bound) then
@@ -100,8 +102,10 @@ trait ConstraintHandling {
100102
val dropWildcards = new ApproximatingTypeMap:
101103
if !isUpper then variance = -1
102104
def apply(t: Type): Type = t match
103-
case WildcardType => range(param.underlying.loBound, param.underlying.hiBound)
104-
case _ => mapOver(t)
105+
case WildcardType if !allowWildcards =>
106+
range(param.underlying.loBound, param.underlying.hiBound)
107+
case _ =>
108+
mapOver(t)
105109
// Narrow one of the bounds of type parameter `param`
106110
// If `isUpper` is true, ensure that `param <: `bound`, otherwise ensure
107111
// that `param >: bound`.

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
139139
try topLevelSubType(tp1, tp2)
140140
finally useNecessaryEither = saved
141141

142+
override protected def allowWildcards: Boolean = !useNecessaryEither
143+
142144
def testSubType(tp1: Type, tp2: Type): CompareResult =
143145
GADTused = false
144146
if !topLevelSubType(tp1, tp2) then CompareResult.Fail

0 commit comments

Comments
 (0)