Skip to content

Commit

Permalink
Support inline unapply extension methods
Browse files Browse the repository at this point in the history
Fixes the computation of the inline unapply temporary unanimous unapply placeholder.

Fixes #8577
  • Loading branch information
gorilskij authored and nicolasstucki committed Nov 17, 2022
1 parent 14f3793 commit 5fc9776
Show file tree
Hide file tree
Showing 26 changed files with 304 additions and 8 deletions.
9 changes: 1 addition & 8 deletions compiler/src/dotty/tools/dotc/inlines/Inlines.scala
Original file line number Diff line number Diff line change
Expand Up @@ -199,14 +199,7 @@ object Inlines:
var unapplySym1: Symbol = NoSymbol // created from within AnonClass() and used afterwards

val newUnapply = AnonClass(ctx.owner, List(defn.ObjectType), sym.coord) { cls =>
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 unapplySym = newSymbol(cls, sym.name.toTermName, Synthetic | Method, unapplyInfo, coord = sym.coord).entered
val unapplySym = newSymbol(cls, sym.name.toTermName, Synthetic | Method, fun.tpe.widen, coord = sym.coord).entered
val unapply = DefDef(unapplySym.asTerm, argss =>
inlineCall(fun.appliedToArgss(argss).withSpan(unapp.span))(using ctx.withOwner(unapplySym))
)
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 5fc9776

Please sign in to comment.