Skip to content

Commit ed74ea9

Browse files
committed
Fix scala#1857: Consider tvars in bounds of uninstantiated tvars
Given: val f: Foo = new Foo def wrap2a[A, W <: Wrapper[A]](host: A)(implicit w: W): W = ??? wrap2a(f) We need to instantiate `A` before doing the implicit search for `w` because it was constrained by the first parameter list. This was not done before because we did not traverse the constraint bounds of an uninstantiated type variable.
1 parent 1197257 commit ed74ea9

File tree

3 files changed

+56
-3
lines changed

3 files changed

+56
-3
lines changed

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@ object Inferencing {
7979
case _: WildcardType | _: ProtoType =>
8080
false
8181
case tvar: TypeVar
82-
if !tvar.isInstantiated && ctx.typerState.constraint.contains(tvar) =>
83-
force.appliesTo(tvar) && {
82+
if !tvar.isInstantiated && ctx.typerState.constraint.contains(tvar) =>
83+
val forceApplies = force.appliesTo(tvar)
84+
if (forceApplies) {
8485
val direction = instDirection(tvar.origin)
8586
if (direction != 0) {
8687
//if (direction > 0) println(s"inst $tvar dir = up")
@@ -95,8 +96,13 @@ object Inferencing {
9596
if (minimize) instantiate(tvar, fromBelow = true)
9697
else toMaximize = true
9798
}
98-
foldOver(x, tvar)
9999
}
100+
foldOver(x && forceApplies,
101+
if (tvar.isInstantiated) tvar
102+
else ctx.typerState.constraint.entry(tvar.origin)
103+
)
104+
case tp: PolyParam =>
105+
apply(x, ctx.typerState.constraint.typeVarOfParam(tp))
100106
case tp =>
101107
foldOver(x, tp)
102108
}

tests/pos/i1857a.scala

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class Wrapper[Host]
2+
3+
4+
class SubWrapper extends Wrapper[Foo]
5+
6+
class Foo
7+
object Foo {
8+
implicit val fooWrapper: SubWrapper = new SubWrapper
9+
}
10+
11+
class Inv[A, B]
12+
13+
object RunMe {
14+
def main(args: Array[String]): Unit = {
15+
def wrap1a[A, W <: Wrapper[Foo]](host: A)(implicit w: W): W = ???
16+
def wrap1b[A, W <: Wrapper[Foo]](host: A)(implicit w: W): A = ???
17+
def wrap1c[A, W <: Wrapper[Foo]](host: A)(implicit w: W): Inv[W, A] = ???
18+
def wrap1d[A, W <: Wrapper[Foo]](host: A)(implicit w: W): Nothing = ???
19+
20+
def wrap2a[A, W <: Wrapper[A]](host: A)(implicit w: W): W = ???
21+
def wrap2b[A, W <: Wrapper[A]](host: A)(implicit w: W): A = ???
22+
def wrap2c[A, W <: Wrapper[A]](host: A)(implicit w: W): Inv[W, A] = ???
23+
def wrap2d[A, W <: Wrapper[A]](host: A)(implicit w: W): Nothing = ???
24+
25+
val f: Foo = new Foo
26+
27+
// work with master
28+
wrap1a(f)
29+
wrap1b(f)
30+
wrap1c(f)
31+
wrap1d(f)
32+
33+
// do not work with master
34+
wrap2a(f)
35+
wrap2b(f)
36+
wrap2c(f)
37+
wrap2d(f)
38+
}
39+
}

tests/pos/tparam_inf.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ object Test {
2323
foo2(10)
2424
}
2525

26+
def test1b: Unit = {
27+
implicit val ii: Int = 42
28+
implicit val ss: String = "foo"
29+
30+
foo1(10)
31+
foo2(10)
32+
}
33+
2634
def hf[T]: HasFoo[T] = ???
2735
def test2: Unit = {
2836
implicit val ii: Int = 42

0 commit comments

Comments
 (0)