How does Scala's implicit resolution mechanism work?
Instruction: Explain the process and rules Scala follows to resolve implicits.
Updated
Implicit resolution supplies a missing contextual argument at compile time. In Scala 3, using declares the requirement and given defines a candidate; the older implicit syntax uses related resolution rules.
The compiler considers eligible contextual definitions visible at the call site, including applicable imports and inherited members, and the required type's implicit scope, which includes relevant companion objects. It checks candidate types and may recursively search for a candidate's own context requirements. This is not a fixed search through four arbitrary locations or a runtime scan of every method parameter type.
trait Render[A] { def show(value: A): String }
object Render {
given Render[Int] with {
def show(value: Int): String = value.toString
}
given [A](using element: Render[A]): Render[Option[A]] with {
def show(value: Option[A]): String =
value.map(element.show).getOrElse("none")
}
}
def format[A](value: A)(using renderer: Render[A]): String =
renderer.show(value)
@main def resolutionExample(): Unit = {
assert(format(7) == "7")
assert(format(Option(7)) == "7")
assert(format(Option.empty[Int]) == "none")
val labelled = new Render[Int] {
def show(value: Int): String = s"number=$value"
}
assert(format(7)(using labelled) == "number=7")
}
The companion supplies Render[Int] without an import. Deriving the option renderer also requires an element renderer. Candidate specificity and, in Scala 3, nesting affect selection; merely having two candidates does not always mean ambiguity. If no applicable candidate exists, or equally suitable alternatives remain, compilation fails. Supplying an explicit using argument avoids searching for that argument. Scala 3 resolution rules
Keep instances discoverable and inspect the compiler's diagnostic when resolution fails. Rules differ across Scala versions, so check the project's compiler version when migrating a complex implicit hierarchy.