Skip to content

Commit 2a80b3b

Browse files
committed
Refactor IsFullyDefinedAccumulator
Refactoring to make it clearer what it does
1 parent c252ffd commit 2a80b3b

File tree

1 file changed

+31
-20
lines changed

1 file changed

+31
-20
lines changed

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

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ 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, allowBottom = false)).process(tp)
49+
new IsFullyDefinedAccumulator(new ForceDegree.Value(tvars.contains, minimizeAll = true)).process(tp)
5050

5151
/** Instantiate any type variables in `tp` whose bounds contain a reference to
5252
* one of the parameters in `tparams` or `vparamss`.
@@ -90,7 +90,8 @@ object Inferencing {
9090
* 2nd Phase: If first phase was successful, instantiate all remaining type variables
9191
* to their upper bound.
9292
*/
93-
private class IsFullyDefinedAccumulator(force: ForceDegree.Value)(implicit ctx: Context) extends TypeAccumulator[Boolean] {
93+
private class IsFullyDefinedAccumulator(force: ForceDegree.Value, minimizeConstrained: Boolean = false)
94+
(implicit ctx: Context) extends TypeAccumulator[Boolean] {
9495

9596
private def instantiate(tvar: TypeVar, fromBelow: Boolean): Type = {
9697
val inst = tvar.instantiate(fromBelow)
@@ -108,14 +109,23 @@ object Inferencing {
108109
&& ctx.typerState.constraint.contains(tvar)
109110
&& {
110111
val direction = instDirection(tvar.origin)
111-
def preferMin =
112-
force.minimizeAll && (tvar.hasLowerBound || !tvar.hasUpperBound)
113-
|| variance >= 0 && (force.allowBottom || tvar.hasLowerBound)
114-
if (direction != 0) instantiate(tvar, direction < 0)
115-
else if (preferMin)
116-
if force.minimizeAll && !tvar.hasLowerBound then () // do nothing
117-
else instantiate(tvar, fromBelow = true)
118-
else toMaximize = tvar :: toMaximize
112+
direction match
113+
case Covariant =>
114+
instantiate(tvar, fromBelow = true)
115+
case Contravariant =>
116+
instantiate(tvar, fromBelow = false)
117+
case EmptyFlags =>
118+
if force.minimizeAll then
119+
if tvar.hasLowerBound then instantiate(tvar, fromBelow = true)
120+
else if tvar.hasUpperBound then instantiate(tvar, fromBelow = false)
121+
else () // hold off instantiating unbounded unconstrained variables
122+
else if variance >= 0 && (force.allowBottom || tvar.hasLowerBound)
123+
then instantiate(tvar, fromBelow = true)
124+
else toMaximize = tvar :: toMaximize
125+
case VarianceFlags =>
126+
if force.minimizeAll || variance >= 0
127+
then instantiate(tvar, fromBelow = true)
128+
else toMaximize = tvar :: toMaximize
119129
foldOver(x, tvar)
120130
}
121131
case tp =>
@@ -220,20 +230,21 @@ object Inferencing {
220230
}
221231

222232
/** The instantiation direction for given poly param computed
223-
* from the constraint:
224-
* @return 1 (maximize) if constraint is uniformly from above,
225-
* -1 (minimize) if constraint is uniformly from below,
226-
* 0 if unconstrained, or constraint is from below and above.
233+
* from the constraint, given as a flag subset of {Covariant, Contravariant}.
234+
* @return a subset of {Covariant, Contravariant} that contains
235+
* Covarant (minimize) if there is a constraint from below that is not subsumed
236+
* by the lower bound
237+
* Contravariant (maximize) if there is a constraint from above that is not subsumed
238+
* by the uppwe bound
227239
*/
228-
private def instDirection(param: TypeParamRef)(implicit ctx: Context): Int = {
240+
private def instDirection(param: TypeParamRef)(implicit ctx: Context): FlagSet = {
229241
val constrained = ctx.typeComparer.fullBounds(param)
230242
val original = param.binder.paramInfos(param.paramNum)
231243
val cmp = ctx.typeComparer
232-
val approxBelow =
233-
if (!cmp.isSubTypeWhenFrozen(constrained.lo, original.lo)) 1 else 0
234-
val approxAbove =
235-
if (!cmp.isSubTypeWhenFrozen(original.hi, constrained.hi)) 1 else 0
236-
approxAbove - approxBelow
244+
var flags = EmptyFlags
245+
if !cmp.isSubTypeWhenFrozen(constrained.lo, original.lo) then flags |= Covariant
246+
if !cmp.isSubTypeWhenFrozen(original.hi, constrained.hi) then flags |= Contravariant
247+
flags
237248
}
238249

239250
/** Following type aliases and stripping refinements and annotations, if one arrives at a

0 commit comments

Comments
 (0)