Skip to content

Implicit resolution fails when overriding trait method with refined result type #9290

@scabug

Description

@scabug

I just noticed that I broke a library of mine by overriding a trait method in a sub-trait that refines a return type. After introducing this override, implicit resolution is suddenly broken.

The scenario is a bit involved, so please excuse the length of the example.

{code:title=example.scala}
trait Serializer[-Tx, A]

trait Source[-Tx, A] {
def apply()(implicit tx: Tx): A
}

trait Txn[S <: Sys[S]] {
def newHandle[A](value: A)(implicit serializer: Serializer[S#Tx, A]): Source[S#Tx, A]
}

trait Sys[S <: Sys[S]] {
type Tx <: Txn[S]
}

object Foo {
implicit def serializer[S <: Sys[S]]: Serializer[S#Tx, Foo[S]] = ???
}
trait Foo[S <: Sys[S]]

// generic -- works
trait Test1[S <: Sys[S]] {
def test(foo: Foo[S])(implicit tx: S#Tx): Unit = tx.newHandle(foo)
}

// ----

// we can use a refined transaction
trait Txn1[S <: Sys1[S]] extends Txn[S] {
def bar: Unit
}

// refined system
trait Sys1[S <: Sys1[S]] extends Sys[S] {
type Tx = Txn1[S]
}
// example system
trait Sys1In extends Sys1[Sys1In]

// specific -- works
trait Test2 {
type S = Sys1In

def test(foo: Foo[S])(implicit tx: S#Tx): Unit = tx.newHandle(foo)
}

// ----

// introduce a refined result type
trait Source2[-Tx, A] extends Source[Tx, A] {
def baz: Unit
}

// and a refined transaction that uses that result type
trait Txn2[S <: Sys2[S]] extends Txn[S] {
override def newHandle[A](value: A)(implicit serializer: Serializer[S#Tx, A]): Source2[S#Tx, A]
}

// refined system
trait Sys2[S <: Sys2[S]] extends Sys[S] {
type Tx = Txn2[S]
}
// example system
trait Sys2In extends Sys2[Sys2In]

// specific -- FAILS
trait Test3 {
type S = Sys2In

// could not find implicit value for parameter serializer
def test(foo: Foo[S])(implicit tx: S#Tx): Unit = tx.newHandle(foo)
}
{code}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions