@@ -55,7 +55,7 @@ object Inferencing {
55
55
def instantiateSelected (tp : Type , tvars : List [Type ])(implicit ctx : Context ): Unit =
56
56
if (tvars.nonEmpty)
57
57
IsFullyDefinedAccumulator (
58
- ForceDegree .Value (tvars.contains, allowBottom = false ), minimizeSelected = true
58
+ ForceDegree .Value (tvars.contains, IfBottom .maximize ), minimizeSelected = true
59
59
).process(tp)
60
60
61
61
/** Instantiate any type variables in `tp` whose bounds contain a reference to
@@ -132,7 +132,9 @@ object Inferencing {
132
132
if tvar.hasLowerBound then instantiate(tvar, fromBelow = true )
133
133
else if tvar.hasUpperBound then instantiate(tvar, fromBelow = false )
134
134
else () // hold off instantiating unbounded unconstrained variables
135
- else if variance >= 0 && (force.allowBottom || tvar.hasLowerBound) then
135
+ else if variance >= 0
136
+ && (force.ifBottom == IfBottom .ok || tvar.hasLowerBound)
137
+ then
136
138
instantiate(tvar, fromBelow = true )
137
139
else
138
140
toMaximize = tvar :: toMaximize
@@ -150,9 +152,14 @@ object Inferencing {
150
152
if ! tvar.isInstantiated then
151
153
instantiate(tvar, fromBelow = false )
152
154
case nil =>
153
- val res = apply(true , tp)
154
- if res then maximize(toMaximize)
155
- res
155
+ apply(true , tp)
156
+ && (
157
+ toMaximize.isEmpty
158
+ || { maximize(toMaximize)
159
+ toMaximize = Nil // Do another round since the maximixing instances
160
+ process(tp) // might have type uninstantiated variables themselves.
161
+ }
162
+ )
156
163
}
157
164
158
165
/** For all type parameters occurring in `tp`:
@@ -508,10 +515,15 @@ trait Inferencing { this: Typer =>
508
515
}
509
516
510
517
/** An enumeration controlling the degree of forcing in "is-dully-defined" checks. */
511
- @ sharable object ForceDegree {
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 )
516
- }
518
+ @ sharable object ForceDegree :
519
+ class Value (val appliesTo : TypeVar => Boolean , val ifBottom : IfBottom )
520
+ val none : Value = new Value (_ => false , ifBottom = IfBottom .ok)
521
+ val all : Value = new Value (_ => true , ifBottom = IfBottom .ok)
522
+ val noBottom : Value = new Value (_ => true , ifBottom = IfBottom .maximize)
523
+
524
+ /** How to react when trying to instantiate a type variable without lower bound */
525
+ enum IfBottom :
526
+ case ok // instantiate to Nothing
527
+ case maximize // maximize to upper bound
528
+ case maximizeUpTo(tp : Type ) // maximize to glb of upper bound and `tp`.
517
529
0 commit comments