@@ -45,9 +45,12 @@ object Inferencing {
45
45
else throw new Error (i " internal error: type of $what $tp is not fully defined, pos = $pos" ) // !!! DEBUG
46
46
47
47
48
- /** Instantiate selected type variables `tvars` in type `tp` */
48
+ /** Instantiate selected type variables `tvars` in type `tp`. Instantiation
49
+ * proceeds with `implicitMode = true`, that is, type variables are approximated
50
+ * from below using or-dominators.
51
+ */
49
52
def instantiateSelected (tp : Type , tvars : List [Type ])(implicit ctx : Context ): Unit =
50
- new IsFullyDefinedAccumulator (new ForceDegree .Value (tvars.contains, minimizeAll = true )).process(tp)
53
+ new IsFullyDefinedAccumulator (new ForceDegree .Value (tvars.contains, implicitMode = true )).process(tp)
51
54
52
55
/** The accumulator which forces type variables using the policy encoded in `force`
53
56
* and returns whether the type is fully defined. The direction in which
@@ -81,14 +84,25 @@ object Inferencing {
81
84
case tvar : TypeVar
82
85
if ! tvar.isInstantiated && ctx.typerState.constraint.contains(tvar) =>
83
86
force.appliesTo(tvar) && {
87
+ if (force.implicitMode) {
88
+ // instantiate to or-dominator of lower bound; without this tweak we'd
89
+ // fail to find an implicit in situations like this:
90
+ //
91
+ // def f[T: Ordering](xs: T*) = ...
92
+ // f(Some(1), None)
93
+ //
94
+ // The problem is that there is no implicit Ordering instance for the otherwise inferred
95
+ // lower bound of T, which is `Some[Int] | None`.
96
+ ctx.orDominator(ctx.typeComparer.bounds(tvar.origin).lo) <:< tvar.origin
97
+ }
84
98
val direction = instDirection(tvar.origin)
85
99
if (direction != 0 ) {
86
100
// if (direction > 0) println(s"inst $tvar dir = up")
87
101
instantiate(tvar, direction < 0 )
88
102
}
89
103
else {
90
104
val minimize =
91
- force.minimizeAll ||
105
+ force.implicitMode ||
92
106
variance >= 0 && ! (
93
107
force == ForceDegree .noBottom &&
94
108
defn.isBottomType(ctx.typeComparer.approximation(tvar.origin, fromBelow = true )))
@@ -366,9 +380,9 @@ object Inferencing {
366
380
367
381
/** An enumeration controlling the degree of forcing in "is-dully-defined" checks. */
368
382
@ sharable object ForceDegree {
369
- class Value (val appliesTo : TypeVar => Boolean , val minimizeAll : Boolean )
370
- val none = new Value (_ => false , minimizeAll = false )
371
- val all = new Value (_ => true , minimizeAll = false )
372
- val noBottom = new Value (_ => true , minimizeAll = false )
383
+ class Value (val appliesTo : TypeVar => Boolean , val implicitMode : Boolean )
384
+ val none = new Value (_ => false , implicitMode = false )
385
+ val all = new Value (_ => true , implicitMode = false )
386
+ val noBottom = new Value (_ => true , implicitMode = false )
373
387
}
374
388
0 commit comments