Skip to content

Commit 0c42378

Browse files
committed
Further tweaks to isFullyDefinedAccumulator
1 parent 2a80b3b commit 0c42378

File tree

2 files changed

+26
-18
lines changed

2 files changed

+26
-18
lines changed

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -555,17 +555,17 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
555555

556556
val childTp = if (child.isTerm) child.termRef else child.typeRef
557557

558-
instantiate(childTp, parent)(ctx.fresh.setNewTyperState()).dealias
558+
instantiateToSubType(childTp, parent)(ctx.fresh.setNewTyperState()).dealias
559559
}
560560

561561
/** Instantiate type `tp1` to be a subtype of `tp2`
562562
*
563-
* Return the instantiated type if type parameters and this type
563+
* Return the instantiated type if type parameters in this type
564564
* in `tp1` can be instantiated such that `tp1 <:< tp2`.
565565
*
566566
* Otherwise, return NoType.
567567
*/
568-
private def instantiate(tp1: NamedType, tp2: Type)(implicit ctx: Context): Type = {
568+
private def instantiateToSubType(tp1: NamedType, tp2: Type)(implicit ctx: Context): Type = {
569569
/** expose abstract type references to their bounds or tvars according to variance */
570570
class AbstractTypeMap(maximize: Boolean)(implicit ctx: Context) extends TypeMap {
571571
def expose(lo: Type, hi: Type): Type =
@@ -637,7 +637,6 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
637637
tvar =>
638638
!(ctx.typerState.constraint.entry(tvar.origin) `eq` tvar.origin.underlying) ||
639639
(tvar `eq` removeThisType.prefixTVar),
640-
minimizeAll = false,
641640
allowBottom = false
642641
)
643642

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

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ object Inferencing {
4646
/** Instantiate selected type variables `tvars` in type `tp` */
4747
def instantiateSelected(tp: Type, tvars: List[Type])(implicit ctx: Context): Unit =
4848
if (tvars.nonEmpty)
49-
new IsFullyDefinedAccumulator(new ForceDegree.Value(tvars.contains, minimizeAll = true)).process(tp)
49+
IsFullyDefinedAccumulator(
50+
ForceDegree.Value(tvars.contains, allowBottom = false), minimizeSelected = true
51+
).process(tp)
5052

5153
/** Instantiate any type variables in `tp` whose bounds contain a reference to
5254
* one of the parameters in `tparams` or `vparamss`.
@@ -78,19 +80,26 @@ object Inferencing {
7880
* 2. T is maximized if the constraint over T is only from above (i.e.
7981
* constrained upper bound != given upper bound and
8082
* constrained lower bound == given lower bound).
81-
* If (1) and (2) do not apply:
82-
* 3. T is minimized if forceDegree is minimizeAll.
83-
* 4. Otherwise, T is maximized if it appears only contravariantly in the given type,
84-
* or if forceDegree is `noBottom` and T's minimized value is a bottom type.
85-
* 5. Otherwise, T is minimized.
8683
*
87-
* The instantiation is done in two phases:
84+
* If (1) and (2) do not apply, and minimizeSelected is set:
85+
* 3. T is minimized if it has a lower bound (different from Nothing) in the
86+
* current constraint (the bound might come from T's declaration).
87+
* 4. Otherwise, T is maximized if it has an upper bound (different from Any)
88+
* in the currented constraint (the bound might come from T's declaration).
89+
* 5. Otherwise, T is not instantiated at all.
90+
91+
* If (1) and (2) do not apply, and minimizeSelected is not set:
92+
* 6: T is maximized if it appears only contravariantly in the given type,
93+
* or if forceDegree is `noBottom` and T has no lower bound different from Nothing.
94+
* 7. Otherwise, T is minimized.
95+
*
96+
* The instantiation for (6) and (7) is done in two phases:
8897
* 1st Phase: Try to instantiate minimizable type variables to
8998
* their lower bound. Record whether successful.
9099
* 2nd Phase: If first phase was successful, instantiate all remaining type variables
91100
* to their upper bound.
92101
*/
93-
private class IsFullyDefinedAccumulator(force: ForceDegree.Value, minimizeConstrained: Boolean = false)
102+
private class IsFullyDefinedAccumulator(force: ForceDegree.Value, minimizeSelected: Boolean = false)
94103
(implicit ctx: Context) extends TypeAccumulator[Boolean] {
95104

96105
private def instantiate(tvar: TypeVar, fromBelow: Boolean): Type = {
@@ -115,15 +124,15 @@ object Inferencing {
115124
case Contravariant =>
116125
instantiate(tvar, fromBelow = false)
117126
case EmptyFlags =>
118-
if force.minimizeAll then
127+
if minimizeSelected then
119128
if tvar.hasLowerBound then instantiate(tvar, fromBelow = true)
120129
else if tvar.hasUpperBound then instantiate(tvar, fromBelow = false)
121130
else () // hold off instantiating unbounded unconstrained variables
122131
else if variance >= 0 && (force.allowBottom || tvar.hasLowerBound)
123132
then instantiate(tvar, fromBelow = true)
124133
else toMaximize = tvar :: toMaximize
125134
case VarianceFlags =>
126-
if force.minimizeAll || variance >= 0
135+
if minimizeSelected || variance >= 0
127136
then instantiate(tvar, fromBelow = true)
128137
else toMaximize = tvar :: toMaximize
129138
foldOver(x, tvar)
@@ -500,9 +509,9 @@ trait Inferencing { this: Typer =>
500509

501510
/** An enumeration controlling the degree of forcing in "is-dully-defined" checks. */
502511
@sharable object ForceDegree {
503-
class Value(val appliesTo: TypeVar => Boolean, val minimizeAll: Boolean, val allowBottom: Boolean = true)
504-
val none: Value = new Value(_ => false, minimizeAll = false)
505-
val all: Value = new Value(_ => true, minimizeAll = false)
506-
val noBottom: Value = new Value(_ => true, minimizeAll = false, allowBottom = false)
512+
class Value(val appliesTo: TypeVar => Boolean, val allowBottom: Boolean)
513+
val none: Value = new Value(_ => false, allowBottom = true)
514+
val all: Value = new Value(_ => true, allowBottom = true)
515+
val noBottom: Value = new Value(_ => true, allowBottom = false)
507516
}
508517

0 commit comments

Comments
 (0)