Skip to content

Commit

Permalink
Support inline unapply extension methods
Browse files Browse the repository at this point in the history
  • Loading branch information
gorilskij authored and nicolasstucki committed Jul 8, 2022
1 parent 80f67df commit d0138bf
Show file tree
Hide file tree
Showing 26 changed files with 307 additions and 11 deletions.
15 changes: 4 additions & 11 deletions compiler/src/dotty/tools/dotc/inlines/Inlines.scala
Original file line number Diff line number Diff line change
Expand Up @@ -190,20 +190,13 @@ object Inlines:
val cls = newNormalizedClassSymbol(ctx.owner, tpnme.ANON_CLASS, Synthetic | Final, List(defn.ObjectType), coord = sym.coord)
val constr = newConstructor(cls, Synthetic, Nil, Nil, coord = sym.coord).entered

val targs = fun match
case TypeApply(_, targs) => targs
case _ => Nil
val unapplyInfo = sym.info match
case info: PolyType => info.instantiate(targs.map(_.tpe))
case info => info

val unappplySym = newSymbol(cls, sym.name.toTermName, Synthetic | Method, unapplyInfo, coord = sym.coord).entered
val unapply = DefDef(unappplySym, argss =>
inlineCall(fun.appliedToArgss(argss).withSpan(unapp.span))(using ctx.withOwner(unappplySym))
val unapplySym = newSymbol(cls, sym.name.toTermName, Synthetic | Method, fun.tpe.widen, coord = sym.coord).entered
val unapply = DefDef(unapplySym, argss =>
inlineCall(fun.appliedToArgss(argss).withSpan(unapp.span))(using ctx.withOwner(unapplySym))
)
val cdef = ClassDef(cls, DefDef(constr), List(unapply))
val newUnapply = Block(cdef :: Nil, New(cls.typeRef, Nil))
val newFun = newUnapply.select(unappplySym).withSpan(unapp.span)
val newFun = newUnapply.select(unapplySym).withSpan(unapp.span)
cpy.UnApply(unapp)(newFun, implicits, patterns)
end inlinedUnapply

Expand Down
11 changes: 11 additions & 0 deletions tests/pos-macros/i8577a/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package i8577

import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

def implUnapply(sc: Expr[Macro.StrCtx], input: Expr[Int])(using Quotes): Expr[Option[Seq[Int]]] =
'{ Some(Seq(${input})) }
9 changes: 9 additions & 0 deletions tests/pos-macros/i8577a/Main_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package i8577

def main: Unit =
extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension (inline ctx: Macro.StrCtx) inline def unapplySeq(inline input: Int): Option[Seq[Int]] =
${ implUnapply('ctx, 'input) }

val mac"$x" = 1
assert(x == 1)
11 changes: 11 additions & 0 deletions tests/pos-macros/i8577b/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package i8577

import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

def implUnapply[U](sc: Expr[Macro.StrCtx], input: Expr[U])(using Type[U])(using Quotes): Expr[Option[Seq[U]]] =
'{ Some(Seq(${input})) }
9 changes: 9 additions & 0 deletions tests/pos-macros/i8577b/Main_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package i8577

def main: Unit =
extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension (inline ctx: Macro.StrCtx) inline def unapplySeq[U](inline input: U): Option[Seq[U]] =
${ implUnapply('ctx, 'input) }

val mac"$x" = 1
assert(x == 1)
11 changes: 11 additions & 0 deletions tests/pos-macros/i8577c/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package i8577

import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

def implUnapply[T](sc: Expr[Macro.StrCtx], input: Expr[T])(using Type[T])(using Quotes): Expr[Option[Seq[T]]] =
'{ Some(Seq(${input})) }
9 changes: 9 additions & 0 deletions tests/pos-macros/i8577c/Main_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package i8577

def main: Unit =
extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension [T] (inline ctx: Macro.StrCtx) inline def unapplySeq(inline input: T): Option[Seq[T]] =
${ implUnapply('ctx, 'input) }

val mac"$x" = 1
assert(x == 1)
11 changes: 11 additions & 0 deletions tests/pos-macros/i8577d/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package i8577

import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

def implUnapply[T](sc: Expr[Macro.StrCtx], input: Expr[T])(using Type[T])(using Quotes): Expr[Option[Seq[T]]] =
'{ Some(Seq(${input})) }
9 changes: 9 additions & 0 deletions tests/pos-macros/i8577d/Main_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package i8577

def main: Unit =
extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension [T] (inline ctx: Macro.StrCtx) inline def unapplySeq[U](inline input: T): Option[Seq[T]] =
${ implUnapply('ctx, 'input) }

val mac"$x" = 1
assert(x == 1)
11 changes: 11 additions & 0 deletions tests/pos-macros/i8577e/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package i8577

import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

def implUnapply[T, U](sc: Expr[Macro.StrCtx], input: Expr[U])(using Type[U])(using Quotes): Expr[Option[Seq[U]]] =
'{ Some(Seq(${input})) }
9 changes: 9 additions & 0 deletions tests/pos-macros/i8577e/Main_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package i8577

def main: Unit =
extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension [T] (inline ctx: Macro.StrCtx) inline def unapplySeq[U](inline input: U): Option[Seq[U]] =
${ implUnapply('ctx, 'input) }

val mac"$x" = 1
assert(x == 1)
11 changes: 11 additions & 0 deletions tests/pos-macros/i8577f/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package i8577

import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

def implUnapply[T, U](sc: Expr[Macro.StrCtx], input: Expr[(T, U)])(using Type[T], Type[U])(using Quotes): Expr[Option[Seq[(T, U)]]] =
'{ Some(Seq(${input})) }
12 changes: 12 additions & 0 deletions tests/pos-macros/i8577f/Main_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package i8577

def main: Unit =
extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension [T] (inline ctx: Macro.StrCtx) inline def unapplySeq[U](inline input: (T, U)): Option[Seq[(T, U)]] =
${ implUnapply('ctx, 'input) }

val mac"$x" = (1, 2)
assert(x == (1, 2))

val mac"$y" = (1, "a")
assert(y == (1, "a"))
11 changes: 11 additions & 0 deletions tests/pos-macros/i8577g/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package i8577

import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

def implUnapply[T, U](sc: Expr[Macro.StrCtx], input: Expr[T | U])(using Type[T], Type[U])(using Quotes): Expr[Option[Seq[T | U]]] =
'{ Some(Seq(${input})) }
9 changes: 9 additions & 0 deletions tests/pos-macros/i8577g/Main_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package i8577

def main: Unit =
extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension [T] (inline ctx: Macro.StrCtx) inline def unapplySeq[U](inline input: T | U): Option[Seq[T | U]] =
${ implUnapply('ctx, 'input) }

val mac"$x" = 1
assert(x == 1)
11 changes: 11 additions & 0 deletions tests/pos-macros/i8577h/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package i8577

import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

def implUnapply[T, U](sc: Expr[Macro.StrCtx], input: Expr[T | U])(using Type[T], Type[U])(using Quotes): Expr[Option[Seq[T | U]]] =
'{ Some(Seq(${input})) }
9 changes: 9 additions & 0 deletions tests/pos-macros/i8577h/Main_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package i8577

def main: Unit =
extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension [T] (inline ctx: Macro.StrCtx) inline def unapplySeq[U](inline input: U | T): Option[Seq[T | U]] =
${ implUnapply('ctx, 'input) }

val mac"$x" = 1
assert(x == 1)
15 changes: 15 additions & 0 deletions tests/run/i8577a.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension (inline ctx: Macro.StrCtx) inline def unapplySeq(inline input: Int): Option[Seq[Int]] =
Some(Seq(input))

@main def Test: Unit =
val mac"$x" = 1
val y: Int = x
assert(x == 1)
15 changes: 15 additions & 0 deletions tests/run/i8577b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension (inline ctx: Macro.StrCtx) inline def unapplySeq[U](inline input: U): Option[Seq[U]] =
Some(Seq(input))

@main def Test: Unit =
val mac"$x" = 1
val y: Int = x
assert(x == 1)
15 changes: 15 additions & 0 deletions tests/run/i8577c.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension [T] (inline ctx: Macro.StrCtx) inline def unapplySeq(inline input: T): Option[Seq[T]] =
Some(Seq(input))

@main def Test: Unit =
val mac"$x" = 1
val y: Int = x
assert(x == 1)
15 changes: 15 additions & 0 deletions tests/run/i8577d.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension [T] (inline ctx: Macro.StrCtx) inline def unapplySeq[U](inline input: T): Option[Seq[T]] =
Some(Seq(input))

@main def Test: Unit =
val mac"$x" = 1
val y: Int = x
assert(x == 1)
19 changes: 19 additions & 0 deletions tests/run/i8577e.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension [T] (inline ctx: Macro.StrCtx) inline def unapplySeq[U](inline input: (T, U)): Option[Seq[(T, U)]] =
Some(Seq(input))

@main def Test: Unit =
val mac"$x" = (1, 2)
val x2: (Int, Int) = x
assert(x == (1, 2))

val mac"$y" = (1, "a")
val y2: (Int, String) = y
assert(y == (1, "a"))
15 changes: 15 additions & 0 deletions tests/run/i8577f.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

@main def Test: Unit =
extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension (inline ctx: Macro.StrCtx) inline def unapplySeq[U](inline input: U): Option[Seq[U]] =
Some(Seq(input))

val mac"$x" = 1
val y: Int = x
assert(x == 1)
15 changes: 15 additions & 0 deletions tests/run/i8577g.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension [T] (inline ctx: Macro.StrCtx) inline def unapplySeq[U](inline input: T | U): Option[Seq[T | U]] =
Some(Seq(input))

@main def Test: Unit =
val mac"$x" = 1
val y: Int = x
assert(x == 1)
15 changes: 15 additions & 0 deletions tests/run/i8577h.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension [T] (inline ctx: Macro.StrCtx) inline def unapplySeq[U](inline input: U | T): Option[Seq[T | U]] =
Some(Seq(input))

@main def Test: Unit =
val mac"$x" = 1
val y: Int = x
assert(x == 1)
16 changes: 16 additions & 0 deletions tests/run/i8577i.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import scala.quoted._

object Macro:
opaque type StrCtx = StringContext
def apply(ctx: StringContext): StrCtx = ctx
def unapply(ctx: StrCtx): Option[StringContext] = Some(ctx)

extension (ctx: StringContext) def mac: Macro.StrCtx = Macro(ctx)
extension (inline ctx: Macro.StrCtx) transparent inline def unapplySeq(inline input: String): Option[Seq[Any]] =
Some(Seq(123))

@main def Test: Unit =
"abc" match
case mac"$x" =>
val y: Int = x
assert(x == 123)

0 comments on commit d0138bf

Please sign in to comment.