@@ -46,7 +46,7 @@ object Inferencing {
46
46
/** Instantiate selected type variables `tvars` in type `tp` */
47
47
def instantiateSelected (tp : Type , tvars : List [Type ])(implicit ctx : Context ): Unit =
48
48
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)
50
50
51
51
/** Instantiate any type variables in `tp` whose bounds contain a reference to
52
52
* one of the parameters in `tparams` or `vparamss`.
@@ -90,7 +90,8 @@ object Inferencing {
90
90
* 2nd Phase: If first phase was successful, instantiate all remaining type variables
91
91
* to their upper bound.
92
92
*/
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 ] {
94
95
95
96
private def instantiate (tvar : TypeVar , fromBelow : Boolean ): Type = {
96
97
val inst = tvar.instantiate(fromBelow)
@@ -108,14 +109,23 @@ object Inferencing {
108
109
&& ctx.typerState.constraint.contains(tvar)
109
110
&& {
110
111
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
119
129
foldOver(x, tvar)
120
130
}
121
131
case tp =>
@@ -220,20 +230,21 @@ object Inferencing {
220
230
}
221
231
222
232
/** 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
227
239
*/
228
- private def instDirection (param : TypeParamRef )(implicit ctx : Context ): Int = {
240
+ private def instDirection (param : TypeParamRef )(implicit ctx : Context ): FlagSet = {
229
241
val constrained = ctx.typeComparer.fullBounds(param)
230
242
val original = param.binder.paramInfos(param.paramNum)
231
243
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
237
248
}
238
249
239
250
/** Following type aliases and stripping refinements and annotations, if one arrives at a
0 commit comments