-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support String interpolator inline unapply
#8577
Comments
|
And requires lampepfl/dotty-feature-requests#112 (or a fix targeted to sting interpolators) |
This would mean we need to allow |
For general unapplies, I mean when used with a match it seems to work already: class Foo(val x: Int, val y: Int)
object Foo { val default = new Foo(0, 0) }
extension (F: Foo.type) def unapply(x: Foo): (Int, Int) = (x.x, x.y)
@main def test(): Unit = new Foo(2, 3) match
case Foo(x, y) => println(x + y) $ scala -3.head foo.scala
5 |
Another idea would be to allow extension modules to give prefixes to extension methods. extension (inline sc: StringContext) object x:
inline def apply(elems: Any*) = ...
inline def unapplySeq() = ... Those objects can only contain methods and can not extend anything. Not sure how this would be encoded. // in a patten
x"abc$d"
// is desugarred as
StringContext("abc").x.apply(d)
// is typed as
x.apply(StringContext("abc"))(d) It should end up desugared into something like this probably. object x:
inline def apply(inline sc: StringContext)(elems: Any*) = ...
inline def unapplySeq(inline sc: StringContext)() = ... |
Just to mention that my current workaround is: extension (inline sc: StringContext)
transparent inline def b: Any = ${ SIParts.scMacro[BParts]('sc) }
class BParts[P <: Tuple](parts: P):
transparent inline def apply(inline args: Any*): Any = ${ applyMacro('parts, 'args) }
transparent inline def unapplySeq(inline arg: Any): Option[Seq[Any]] = ${ unapplySeqMacro('parts, 'arg) } // P is a tuple representation of the SC parts
trait SIParts[P <: Tuple](parts: P)
object SIParts:
def scMacro[SI[_ <: Tuple]](sc: Expr[StringContext])(using
Quotes,
Type[SI]
): Expr[Any] =
import quotes.reflect.*
val '{ StringContext(${ Varargs(args) }*) } = sc
val tplExpr = Expr.ofTupleFromSeq(args)
val tplTpe = tplExpr.asTerm.tpe
val tplType = tplTpe.asTypeOf[Tuple]
val AppliedType(siTpe, _) = TypeRepr.of[SI[Tuple]]
val siSym = siTpe.typeSymbol
val siTree =
New(siTpe.asTypeTree)
.select(siSym.primaryConstructor)
.appliedToType(tplTpe)
.appliedTo(tplExpr.asTerm)
siTree.asExpr
end scMacro |
Pietro Gorilskij would probably take this as a MSc project during the Spring semester. |
Is this being worked on? |
Yes, this project is taken by Pietro Gorilskij @gorilskij. |
Fixes the computation of the inline unapply temporary unanimous unapply placeholder. Fixes scala#8577
Fixes the computation of the inline unapply temporary unanimous unapply placeholder. Fixes scala#8577
Fixes the computation of the inline unapply temporary unanimous unapply placeholder. Fixes scala#8577 Fixes scala#15188
Fixes the computation of the inline unapply temporary unanimous unapply placeholder. Fixes scala#8577 Fixes scala#15188
* Fixes the computation of the inline unapply temporary unanimous unapply placeholder * Handle leading given parameters in inline unapplies Fixes scala#8577 Fixes scala#12991 Fixes scala#15188
* Fixes the computation of the inline unapply temporary unanimous unapply placeholder * Handle leading given parameters in inline unapplies Fixes scala#8577 Fixes scala#12991 Fixes scala#15188
To write a string interpolator with an
apply
andunapply
. Both could be macros.old code
In Scala 2 we would have written
Possible encoding
A possible encoding in Dotty is
This encoding ensures that both the
StringContext
and arguments are inlined and accessible by the macro.The
apply
can work out of the box forx"..."
, even with a macro (see #8572).But
unapply
is not taken into account, even without macros.expectation
should compile.
Detailed description of the Semester project
Problem
We want to implement string interpolation extractors using macros:
The problem is that the old, Scala 2, encoding involves passing
StringContext
, which is an argument to theimplicit class
, to the macro that implements the extractor. We need to passStringContext
because it contains all the information on the string being extracted, and the macro needs that information to be useful. However, being a constructor argument to a class,StringContext
is not statically known. Hence, it cannot be passed to a macro since being statically known is a requirement for (inlined) macro arguments.Solution
Investigate possible encodings for the string interpolator macro-based extractors. The output of the project will be a report on the encodings investigated and why they can or cannot be used. Ideally, if a good solution is found, you can also implement it as part of the semester project, but this is not mandatory.
The text was updated successfully, but these errors were encountered: