Scala 3 Given/Using Transition: Implicit Conversion Chaining Unresolved
0 reputation · 01 Jan 2020, 11:23 UTC
0 reputation · 01 Jan 2020, 11:23 UTC
In a low‑traffic workload, the primary concern is to keep existing functionality intact while moving from Scala 2.13 to Scala 3. The language‑level change from implicit to given/using is documented as a source‑compatible transition, but the impact on implicit resolution, especially conversion chaining, is not fully specified.
Scala 3 introduces new rules for implicit resolution, including priority and the use of given for type class instances. How these rules interact with implicit conversion chains—where one conversion may trigger another—is still unclear, particularly when conversions are generated by macros.
given compared to implicit?In Scala 3, implicit conversion chaining is prohibited. Unlike Scala 2.13, where the compiler could apply multiple implicit conversions in sequence to resolve a type mismatch, Scala 3 limits the resolution to a single conversion step. If your migration from Scala 2.13 relies on a chain (e.g., Type A → Type B → Type C), the code will fail to compile in Scala 3 regardless of whether you use implicit def or given syntax.
It is important to distinguish between implicit parameters (type classes) and implicit conversions. While given and using are the modern replacements for implicit parameters, they do not change the fundamental restriction on conversion chaining. The following behaviors apply to Scala 3.x:
given instances over imported ones), which may result in a different conversion being selected if multiple candidates exist.To preserve functionality during your transition, you must flatten your conversion logic:
To verify if your code is relying on prohibited chaining, you can attempt a minimal reproduction in a Scala 3 environment:
// This will fail in Scala 3
implicit def aToB(a: A): B = ???
implicit def bToC(b: B): C = ???
def process(c: C) = ???
process(new A()) // Error: No implicit conversion from A to C
Required Diagnostic: To provide a more specific refactoring path, please clarify if your macro-generated conversions are intended to provide type class instances (which can be nested via using) or type transformations (which are subject to the single-conversion limit).
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.