Skip to content

Commit ff766a0

Browse files
committed
Clean up logic in isFullyDefinedAccumulator
1 parent 7c1f7f0 commit ff766a0

File tree

2 files changed

+32
-18
lines changed

2 files changed

+32
-18
lines changed

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

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,10 @@ object Inferencing {
7979
* constrained upper bound != given upper bound and
8080
* constrained lower bound == given lower bound).
8181
* If (1) and (2) do not apply:
82-
* 3. T is maximized if it appears only contravariantly in the given type.
83-
* 4. T is minimized in all other cases.
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.
8486
*
8587
* The instantiation is done in two phases:
8688
* 1st Phase: Try to instantiate minimizable type variables to
@@ -89,32 +91,30 @@ object Inferencing {
8991
* to their upper bound.
9092
*/
9193
private class IsFullyDefinedAccumulator(force: ForceDegree.Value)(implicit ctx: Context) extends TypeAccumulator[Boolean] {
94+
9295
private def instantiate(tvar: TypeVar, fromBelow: Boolean): Type = {
9396
val inst = tvar.instantiate(fromBelow)
9497
typr.println(i"forced instantiation of ${tvar.origin} = $inst")
9598
inst
9699
}
100+
97101
private[this] var toMaximize: Boolean = false
102+
98103
def apply(x: Boolean, tp: Type): Boolean = tp.dealias match {
99104
case _: WildcardType | _: ProtoType =>
100105
false
101106
case tvar: TypeVar
102107
if !tvar.isInstantiated && ctx.typerState.constraint.contains(tvar) =>
103108
force.appliesTo(tvar) && {
104-
val direction = instDirection(tvar.origin)
105-
if (direction != 0) {
106-
//if (direction > 0) println(s"inst $tvar dir = up")
107-
instantiate(tvar, direction < 0)
108-
}
109-
else {
110-
val minimize =
111-
force.minimizeAll ||
112-
variance >= 0 && !(
113-
!force.allowBottom &&
114-
defn.isBottomType(ctx.typeComparer.approximation(tvar.origin, fromBelow = true)))
115-
if (minimize) instantiate(tvar, fromBelow = true)
116-
else toMaximize = true
117-
}
109+
val pref = tvar.origin
110+
val direction = instDirection(pref)
111+
def avoidBottom =
112+
!force.allowBottom &&
113+
defn.isBottomType(ctx.typeComparer.approximation(pref, fromBelow = true))
114+
def preferMin = force.minimizeAll || variance >= 0 && !avoidBottom
115+
if (direction != 0) instantiate(tvar, fromBelow = direction < 0)
116+
else if (preferMin) instantiate(tvar, fromBelow = true)
117+
else toMaximize = true
118118
foldOver(x, tvar)
119119
}
120120
case tp =>

tests/pos/i6127.scala

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
1+
import reflect.ClassTag
2+
class Co[+S]
3+
object Co {
4+
def empty[X: ClassTag]: Co[X] = ???
5+
}
6+
class Contra[-S]
7+
object Contra {
8+
def empty[X: ClassTag]: Contra[X] = ???
9+
}
110
class Foo[+FT](x: FT) {
211
def fooArray: Foo[Array[String]] = new Foo(Array.empty)
3-
val y: Array[String] = Array.empty
4-
}
12+
val y1: Array[String] = Array.empty
13+
def fooCo: Foo[Co[String]] = new Foo(Co.empty)
14+
val y2: Co[String] = Co.empty
15+
def fooContra: Foo[Contra[String]] = new Foo(Contra.empty)
16+
val y3: Contra[String] = Contra.empty
17+
}
18+

0 commit comments

Comments
 (0)