diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala index 86649d78ed54..7561d82b3178 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala @@ -79,8 +79,9 @@ object Inferencing { case _: WildcardType | _: ProtoType => false case tvar: TypeVar - if !tvar.isInstantiated && ctx.typerState.constraint.contains(tvar) => - force.appliesTo(tvar) && { + if !tvar.isInstantiated && ctx.typerState.constraint.contains(tvar) => + val forceApplies = force.appliesTo(tvar) + if (forceApplies) { val direction = instDirection(tvar.origin) if (direction != 0) { //if (direction > 0) println(s"inst $tvar dir = up") @@ -95,8 +96,13 @@ object Inferencing { if (minimize) instantiate(tvar, fromBelow = true) else toMaximize = true } - foldOver(x, tvar) } + foldOver(x && forceApplies, + if (tvar.isInstantiated) tvar + else ctx.typerState.constraint.entry(tvar.origin) + ) + case tp: PolyParam => + apply(x, ctx.typerState.constraint.typeVarOfParam(tp)) case tp => foldOver(x, tp) } diff --git a/tests/pos/i1857a.scala b/tests/pos/i1857a.scala new file mode 100644 index 000000000000..750731ccf31a --- /dev/null +++ b/tests/pos/i1857a.scala @@ -0,0 +1,39 @@ +class Wrapper[Host] + + +class SubWrapper extends Wrapper[Foo] + +class Foo +object Foo { + implicit val fooWrapper: SubWrapper = new SubWrapper +} + +class Inv[A, B] + +object RunMe { + def main(args: Array[String]): Unit = { + def wrap1a[A, W <: Wrapper[Foo]](host: A)(implicit w: W): W = ??? + def wrap1b[A, W <: Wrapper[Foo]](host: A)(implicit w: W): A = ??? + def wrap1c[A, W <: Wrapper[Foo]](host: A)(implicit w: W): Inv[W, A] = ??? + def wrap1d[A, W <: Wrapper[Foo]](host: A)(implicit w: W): Nothing = ??? + + def wrap2a[A, W <: Wrapper[A]](host: A)(implicit w: W): W = ??? + def wrap2b[A, W <: Wrapper[A]](host: A)(implicit w: W): A = ??? + def wrap2c[A, W <: Wrapper[A]](host: A)(implicit w: W): Inv[W, A] = ??? + def wrap2d[A, W <: Wrapper[A]](host: A)(implicit w: W): Nothing = ??? + + val f: Foo = new Foo + + // work with master + wrap1a(f) + wrap1b(f) + wrap1c(f) + wrap1d(f) + + // do not work with master + wrap2a(f) + wrap2b(f) + wrap2c(f) + wrap2d(f) + } +} diff --git a/tests/pos/tparam_inf.scala b/tests/pos/tparam_inf.scala index 16d99b75d538..56801fc35744 100644 --- a/tests/pos/tparam_inf.scala +++ b/tests/pos/tparam_inf.scala @@ -23,6 +23,14 @@ object Test { foo2(10) } + def test1b: Unit = { + implicit val ii: Int = 42 + implicit val ss: String = "foo" + + foo1(10) + foo2(10) + } + def hf[T]: HasFoo[T] = ??? def test2: Unit = { implicit val ii: Int = 42