@@ -43,10 +43,20 @@ object Inferencing {
4343 if (isFullyDefined(tp, ForceDegree .all)) tp
4444 else throw new Error (i " internal error: type of $what $tp is not fully defined, pos = $span" ) // !!! DEBUG
4545
46- /** Instantiate selected type variables `tvars` in type `tp` */
46+ /** Instantiate selected type variables `tvars` in type `tp` in a special mode:
47+ * 1. If a type variable is constrained from below (i.e. constraint bound != given lower bound)
48+ * it is minimized.
49+ * 2. Otherwise, if the type variable is constrained from above, it is maximized.
50+ * 3. Otherwise, if the type variable has a lower bound != Nothing, it is minimized.
51+ * 4. Otherwise, if the type variable has an upper bound != Any, it is maximized.
52+ * If none of (1) - (4) applies, the type variable is left uninstantiated.
53+ * The method is called to instantiate type variables before an implicit search.
54+ */
4755 def instantiateSelected (tp : Type , tvars : List [Type ])(implicit ctx : Context ): Unit =
4856 if (tvars.nonEmpty)
49- new IsFullyDefinedAccumulator (new ForceDegree .Value (tvars.contains, minimizeAll = true , allowBottom = false )).process(tp)
57+ IsFullyDefinedAccumulator (
58+ ForceDegree .Value (tvars.contains, allowBottom = false ), minimizeSelected = true
59+ ).process(tp)
5060
5161 /** Instantiate any type variables in `tp` whose bounds contain a reference to
5262 * one of the parameters in `tparams` or `vparamss`.
@@ -78,19 +88,27 @@ object Inferencing {
7888 * 2. T is maximized if the constraint over T is only from above (i.e.
7989 * constrained upper bound != given upper bound and
8090 * 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.
8691 *
87- * The instantiation is done in two phases:
92+ * If (1) and (2) do not apply, and minimizeSelected is set:
93+ * 3. T is minimized if it has a lower bound (different from Nothing) in the
94+ * current constraint (the bound might come from T's declaration).
95+ * 4. Otherwise, T is maximized if it has an upper bound (different from Any)
96+ * in the currented constraint (the bound might come from T's declaration).
97+ * 5. Otherwise, T is not instantiated at all.
98+
99+ * If (1) and (2) do not apply, and minimizeSelected is not set:
100+ * 6: T is maximized if it appears only contravariantly in the given type,
101+ * or if forceDegree is `noBottom` and T has no lower bound different from Nothing.
102+ * 7. Otherwise, T is minimized.
103+ *
104+ * The instantiation for (6) and (7) is done in two phases:
88105 * 1st Phase: Try to instantiate minimizable type variables to
89106 * their lower bound. Record whether successful.
90107 * 2nd Phase: If first phase was successful, instantiate all remaining type variables
91108 * to their upper bound.
92109 */
93- private class IsFullyDefinedAccumulator (force : ForceDegree .Value )(implicit ctx : Context ) extends TypeAccumulator [Boolean ] {
110+ private class IsFullyDefinedAccumulator (force : ForceDegree .Value , minimizeSelected : Boolean = false )
111+ (implicit ctx : Context ) extends TypeAccumulator [Boolean ] {
94112
95113 private def instantiate (tvar : TypeVar , fromBelow : Boolean ): Type = {
96114 val inst = tvar.instantiate(fromBelow)
@@ -108,14 +126,16 @@ object Inferencing {
108126 && ctx.typerState.constraint.contains(tvar)
109127 && {
110128 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
129+ if direction != 0 then
130+ instantiate(tvar, fromBelow = direction < 0 )
131+ else if minimizeSelected then
132+ if tvar.hasLowerBound then instantiate(tvar, fromBelow = true )
133+ else if tvar.hasUpperBound then instantiate(tvar, fromBelow = false )
134+ else () // hold off instantiating unbounded unconstrained variables
135+ else if variance >= 0 && (force.allowBottom || tvar.hasLowerBound) then
136+ instantiate(tvar, fromBelow = true )
137+ else
138+ toMaximize = tvar :: toMaximize
119139 foldOver(x, tvar)
120140 }
121141 case tp =>
@@ -489,9 +509,9 @@ trait Inferencing { this: Typer =>
489509
490510/** An enumeration controlling the degree of forcing in "is-dully-defined" checks. */
491511@ sharable object ForceDegree {
492- class Value (val appliesTo : TypeVar => Boolean , val minimizeAll : Boolean , val allowBottom : Boolean = true )
493- val none : Value = new Value (_ => false , minimizeAll = false )
494- val all : Value = new Value (_ => true , minimizeAll = false )
495- 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 )
496516}
497517
0 commit comments