Default value of implicit parameter defined in package object is not found without explicit import
See original GitHub issueCompiler version
3.0.0-RC1
Minimized code
The issue was found while looking at upgrading the sttp integration for circe to Scala 3 here: https://github.com/softwaremill/sttp/issues/864
The code works as is for Scala 2.
There’s a reproduction here: https://github.com/aeons/default-implicit-repro
It looks like something has changed with how default implicit arguments work if they are used from a package object. There’s a lot of moving parts here.
In the repro, these are the parts:
package repro.circe
trait SttpCirceApi {
implicit def circeBodySerializer[B](implicit
encoder: Encoder[B],
printer: Printer = Printer.noSpaces
): BodySerializer[B] =
b => encoder(b).printWith(printer)
}
package repro
package object circe extends SttpCirceApi
And then we have a test
package repro.circe
import io.circe._
import repro.{BodySerializer, serialize}
case class Inner(a: Int, b: Boolean, c: String)
object Inner {
implicit val encoder: Encoder[Inner] =
Encoder.forProduct3("a", "b", "c")(i => (i.a, i.b, i.c))
}
class CirceTestsWorks {
// This works
import repro.circe._
implicitly[BodySerializer[Inner]]
}
class CirceTestsFails {
// This fails with a missing implicit for Printer
implicitly[BodySerializer[Inner]]
}
Output
[error] -- Error: /home/user/code/default-implicit-repro/src/test/scala/repro/circe/CirceTests.scala:20:35
[error] 20 | implicitly[BodySerializer[Inner]]
[error] | ^
[error] |no implicit argument of type repro.BodySerializer[repro.circe.Inner] was found for parameter e of method implicitly in object Predef.
[error] |I found:
[error] |
[error] | repro.circe.circeBodySerializer[repro.circe.Inner](repro.circe.Inner.encoder,
[error] | /* missing */summon[io.circe.Printer]
[error] | )
[error] |
[error] |But no implicit values were found that match type io.circe.Printer.
Expectation
It compiles and works, as in Scala 2.
Issue Analytics
- State:
- Created 3 years ago
- Comments:7 (3 by maintainers)
Top Results From Across the Web
Scala: How can an import prevent finding an implicit value?
My workaround is to rebind x to an implicit val before the import. Both of the following work:
Read more >revisiting implicits without import tax - eed3si9n
If the parameter has a default argument and no implicit argument can be found the default argument is used. We will look at...
Read more >Chapter 5. Using implicits to write expressive code - Scala in ...
A method call or constructor with a missing parameter. ... Any implicits defined on a package object will be on the implicit scope...
Read more >Contextual Parameters, aka Implicit Parameters | Tour of Scala
A method can have contextual parameters, also called implicit parameters, or more concisely implicits. Parameter lists starting with the keyword using (or ...
Read more >Implicit Implications (part 1): Implicit Parameters - Rally Health
The compiler is just using the rules of implicit searches to provide the ability to prove that one type is a subclass of...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Good news: this got fixed just a few days ago by https://github.com/lampepfl/dotty/pull/13018, so I’ll be closing this (you can try a nightly to check that it’s fixed in the original code too:
scalaVersion := "3.0.2-RC1-bin-20210708-7627583-NIGHTLY"
)Indeed, I’ll remove the tag.