Skip to content

Commit f7da93d

Browse files
committed
Tweak widenAbstractOKFor docs & doc poisoned
1 parent 9416693 commit f7da93d

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ trait ConstraintHandling {
6363
* toplevel; it is turned on again when we add parts of the scrutinee to the constraint.
6464
*/
6565
protected var canWidenAbstract: Boolean = true
66+
67+
/**
68+
* Used for match type reduction.
69+
* When an abstract type may not be widened, according to `widenAbstractOKFor`,
70+
* we record it in this set, so that we can ultimately fail the reduction, but
71+
* with all the information that comes out from continuing to widen the abstract type.
72+
*/
6673
protected var poisoned: Set[TypeParamRef] = Set.empty
6774

6875
protected var myNecessaryConstraintsOnly = false

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -867,10 +867,14 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
867867
}
868868

869869
/** Can we widen an abstract type when comparing with `tp`?
870-
* This is NOT the case if one of the following is true:
871-
* - canWidenAbstract is false,
872-
* - or `tp` contains a non-wildcard type parameter of the matched-against
873-
* case lambda that appears in co- or contra-variant position
870+
* This is the case with the following cases:
871+
* - if `canWidenAbstract` is true.
872+
*
873+
* Secondly, if `tp` is a type parameter, we can widen if:
874+
* - if `tp` is not a type parameter of the matched-against case lambda
875+
* - if `tp` is an invariant or wildcard type parameter
876+
* - finally, allow widening, but record the type parameter in `poisoned`,
877+
* so that can be accounted for during the reduction step
874878
*/
875879
def widenAbstractOKFor(tp: Type): Boolean =
876880
val acc = new TypeAccumulator[Boolean]:
@@ -3114,6 +3118,8 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
31143118
}
31153119

31163120
def matchCases(scrut: Type, cases: List[Type])(using Context): Type = {
3121+
// a reference for the type parameters poisoned during matching
3122+
// for use during the reduction step
31173123
var poisoned: Set[TypeParamRef] = Set.empty
31183124

31193125
def paramInstances(canApprox: Boolean) = new TypeAccumulator[Array[Type]]:

docs/_docs/reference/new-types/match-types.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ An instantiation `Is` is _minimal_ for `Xs` if all type variables in `Xs` that
140140
appear covariantly and nonvariantly in `Is` are as small as possible and all
141141
type variables in `Xs` that appear contravariantly in `Is` are as large as
142142
possible. Here, "small" and "large" are understood with respect to `<:`.
143+
But, type parameter will not be "large" if a pattern containing it is matched
144+
against lambda case in co- or contra-variant position.
143145

144146
For simplicity, we have omitted constraint handling so far. The full formulation
145147
of subtyping tests describes them as a function from a constraint and a pair of

0 commit comments

Comments
 (0)