"no implicit argument of type Nothing" when changing val to def

The following compiles in Scala 2.13. In Scala 3 there is an error on the last line:

no implicit argument of type Nothing was found for parameter bar of method apply in class Foo

Intentional or bug?


class Bar[A]

object Bar {
  implicit def myBar[A <: Foo]: Bar[A] = new Bar[A]
}

class Foo {
  val i = 1
  def apply[Z](f: this.type => Z)(implicit bar: Bar[this.type]) = bar
}

trait Zip {
  val foo: Foo
  def bar = foo(_.i)
  def foo2: Foo
  def bar2 = foo2(_.i)
}

It works in Scala 2 because of “stabilization”, which was added in 2018.

  abstract trait Zip extends scala.AnyRef {
    def /*Zip*/$init$(): Unit = {
      ()
    };
    <stable> <accessor> val foo: Foo;
    def bar: Bar[Zip.this.foo.type] = Zip.this.foo.apply[Int](((x$1: Zip.this.foo.type) => x$1.i))(Bar.myBar[Zip.this.foo.type]);
    def foo2: Foo;
    def bar2: Bar[_ <: Foo with Singleton] = {
      <synthetic> <stable> <artifact> val stabilizer$1: Foo = Zip.this.foo2;
      stabilizer$1.apply[Int](((x$2: stabilizer$1.type) => x$2.i))(Bar.myBar[stabilizer$1.type])
    }
  }

I see Scala 3 doesn’t do that transformation, and it fails a Scala 2 unit test in the same way.

I don’t know if this is an intended limitation or restriction. The feature was intended to support implicit classes, where the “def” was not foo2 but some wrapper(foo2). The extension mechanism is different in Scala 3.

In general, I think you’re supposed to “stabilize manually” by assigning to a val first explicitly.

1 Like