Before deprecating old-style implicit conversions, we need this

First, this thread is not about the potential removal of implicit conversions. For that see the following discussion: Can We Wean Scala Off Implicit Conversions?

This discussion is opened following a SIP committee discussion about the upcoming Scala 3.4 deprecations, and the old-style implicit conversion syntax among them. This deprecation is significant, because it does not account for transparent inline implicit def (whitebox) use-cases.

Generally, I have several different use-cases for implicit conversions, but only one whitebox conversion that has no fallback if this feature is deprecated.

Whitebox implicit conversion for Precise (Exact) types

Scalac, by default, widens the type of an argument when applied to a method.
Like what the refined library is doing, I utilize a whitebox implicit conversion to grab the actual tree and derive the precise type from it. So a method in my code that requires a precise argument look like: def foo[T](arg: Precise[T]) ....
I proposed a language feature that will accommodate this use-case, but it was considered too complicated for not enough use traction.

Proposal: bring back the Scala 2 enclosingImplicits capability (or something equivalent). This will enable creating a whitebox implicit conversion via a helper implicit macro. E.g.:

import scala.quoted.*
class Precise[T](value: T)
object Precise:
  given toPrecise[T](using pf: PreciseFetch): Conversion[T, Precise[pf.Out]] = Precise(t.asInstanceOf[pf.Out])
  trait PreciseFetch:
    type Out
  transparent inline given preciseFetch: PreciseFetch = ${preciseFetchMacro}
  def preciseFetchMacro(using Quotes): Expr[PreciseFetch] =
    import quotes.reflect.enclosingImplicits
    val preciseTpe: TypeRepr = getPreciseTypeFromTree(enclosingImplicits.head.tree)
    val preciseType = preciseTpe.asTypeOf[Any]
    '{new PreciseFetch{type Out = preciseType.Underlying}}
3 Likes