Skip to content

Alternative fix for #1857: Consider tvars in bounds of uninstantiated tvars #1861

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions compiler/src/dotty/tools/dotc/typer/Inferencing.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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)
}
Expand Down
39 changes: 39 additions & 0 deletions tests/pos/i1857a.scala
Original file line number Diff line number Diff line change
@@ -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)
}
}
8 changes: 8 additions & 0 deletions tests/pos/tparam_inf.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down