From 5fc97763a174bfa3f93d45a8769a89aa66b34f1d Mon Sep 17 00:00:00 2001 From: gorilskij <43991400@users.noreply.github.com> Date: Mon, 11 Apr 2022 13:52:40 +0200 Subject: [PATCH] Support inline unapply extension methods Fixes the computation of the inline unapply temporary unanimous unapply placeholder. Fixes #8577 --- .../dotty/tools/dotc/inlines/Inlines.scala | 9 +-------- tests/pos-macros/i8577a/Macro_1.scala | 11 +++++++++++ tests/pos-macros/i8577a/Main_2.scala | 9 +++++++++ tests/pos-macros/i8577b/Macro_1.scala | 11 +++++++++++ tests/pos-macros/i8577b/Main_2.scala | 9 +++++++++ tests/pos-macros/i8577c/Macro_1.scala | 11 +++++++++++ tests/pos-macros/i8577c/Main_2.scala | 9 +++++++++ tests/pos-macros/i8577d/Macro_1.scala | 11 +++++++++++ tests/pos-macros/i8577d/Main_2.scala | 9 +++++++++ tests/pos-macros/i8577e/Macro_1.scala | 11 +++++++++++ tests/pos-macros/i8577e/Main_2.scala | 9 +++++++++ tests/pos-macros/i8577f/Macro_1.scala | 11 +++++++++++ tests/pos-macros/i8577f/Main_2.scala | 12 ++++++++++++ tests/pos-macros/i8577g/Macro_1.scala | 11 +++++++++++ tests/pos-macros/i8577g/Main_2.scala | 9 +++++++++ tests/pos-macros/i8577h/Macro_1.scala | 11 +++++++++++ tests/pos-macros/i8577h/Main_2.scala | 9 +++++++++ tests/run/i8577a.scala | 15 +++++++++++++++ tests/run/i8577b.scala | 15 +++++++++++++++ tests/run/i8577c.scala | 15 +++++++++++++++ tests/run/i8577d.scala | 15 +++++++++++++++ tests/run/i8577e.scala | 19 +++++++++++++++++++ tests/run/i8577f.scala | 15 +++++++++++++++ tests/run/i8577g.scala | 15 +++++++++++++++ tests/run/i8577h.scala | 15 +++++++++++++++ tests/run/i8577i.scala | 16 ++++++++++++++++ 26 files changed, 304 insertions(+), 8 deletions(-) create mode 100644 tests/pos-macros/i8577a/Macro_1.scala create mode 100644 tests/pos-macros/i8577a/Main_2.scala create mode 100644 tests/pos-macros/i8577b/Macro_1.scala create mode 100644 tests/pos-macros/i8577b/Main_2.scala create mode 100644 tests/pos-macros/i8577c/Macro_1.scala create mode 100644 tests/pos-macros/i8577c/Main_2.scala create mode 100644 tests/pos-macros/i8577d/Macro_1.scala create mode 100644 tests/pos-macros/i8577d/Main_2.scala create mode 100644 tests/pos-macros/i8577e/Macro_1.scala create mode 100644 tests/pos-macros/i8577e/Main_2.scala create mode 100644 tests/pos-macros/i8577f/Macro_1.scala create mode 100644 tests/pos-macros/i8577f/Main_2.scala create mode 100644 tests/pos-macros/i8577g/Macro_1.scala create mode 100644 tests/pos-macros/i8577g/Main_2.scala create mode 100644 tests/pos-macros/i8577h/Macro_1.scala create mode 100644 tests/pos-macros/i8577h/Main_2.scala create mode 100644 tests/run/i8577a.scala create mode 100644 tests/run/i8577b.scala create mode 100644 tests/run/i8577c.scala create mode 100644 tests/run/i8577d.scala create mode 100644 tests/run/i8577e.scala create mode 100644 tests/run/i8577f.scala create mode 100644 tests/run/i8577g.scala create mode 100644 tests/run/i8577h.scala create mode 100644 tests/run/i8577i.scala diff --git a/compiler/src/dotty/tools/dotc/inlines/Inlines.scala b/compiler/src/dotty/tools/dotc/inlines/Inlines.scala index c96d6cdf5bfc..543d3d401af0 100644 --- a/compiler/src/dotty/tools/dotc/inlines/Inlines.scala +++ b/compiler/src/dotty/tools/dotc/inlines/Inlines.scala @@ -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)) ) diff --git a/tests/pos-macros/i8577a/Macro_1.scala b/tests/pos-macros/i8577a/Macro_1.scala new file mode 100644 index 000000000000..3831f060f918 --- /dev/null +++ b/tests/pos-macros/i8577a/Macro_1.scala @@ -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})) } diff --git a/tests/pos-macros/i8577a/Main_2.scala b/tests/pos-macros/i8577a/Main_2.scala new file mode 100644 index 000000000000..5a0f6b609f81 --- /dev/null +++ b/tests/pos-macros/i8577a/Main_2.scala @@ -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) diff --git a/tests/pos-macros/i8577b/Macro_1.scala b/tests/pos-macros/i8577b/Macro_1.scala new file mode 100644 index 000000000000..464d9894fa1c --- /dev/null +++ b/tests/pos-macros/i8577b/Macro_1.scala @@ -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})) } diff --git a/tests/pos-macros/i8577b/Main_2.scala b/tests/pos-macros/i8577b/Main_2.scala new file mode 100644 index 000000000000..789e572bd5aa --- /dev/null +++ b/tests/pos-macros/i8577b/Main_2.scala @@ -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) diff --git a/tests/pos-macros/i8577c/Macro_1.scala b/tests/pos-macros/i8577c/Macro_1.scala new file mode 100644 index 000000000000..45986b34d48d --- /dev/null +++ b/tests/pos-macros/i8577c/Macro_1.scala @@ -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})) } diff --git a/tests/pos-macros/i8577c/Main_2.scala b/tests/pos-macros/i8577c/Main_2.scala new file mode 100644 index 000000000000..4f42c7635ec5 --- /dev/null +++ b/tests/pos-macros/i8577c/Main_2.scala @@ -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) diff --git a/tests/pos-macros/i8577d/Macro_1.scala b/tests/pos-macros/i8577d/Macro_1.scala new file mode 100644 index 000000000000..45986b34d48d --- /dev/null +++ b/tests/pos-macros/i8577d/Macro_1.scala @@ -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})) } diff --git a/tests/pos-macros/i8577d/Main_2.scala b/tests/pos-macros/i8577d/Main_2.scala new file mode 100644 index 000000000000..a87f06503b31 --- /dev/null +++ b/tests/pos-macros/i8577d/Main_2.scala @@ -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) diff --git a/tests/pos-macros/i8577e/Macro_1.scala b/tests/pos-macros/i8577e/Macro_1.scala new file mode 100644 index 000000000000..cf133d33a100 --- /dev/null +++ b/tests/pos-macros/i8577e/Macro_1.scala @@ -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})) } diff --git a/tests/pos-macros/i8577e/Main_2.scala b/tests/pos-macros/i8577e/Main_2.scala new file mode 100644 index 000000000000..598d18d2faec --- /dev/null +++ b/tests/pos-macros/i8577e/Main_2.scala @@ -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) diff --git a/tests/pos-macros/i8577f/Macro_1.scala b/tests/pos-macros/i8577f/Macro_1.scala new file mode 100644 index 000000000000..7d3b5df28701 --- /dev/null +++ b/tests/pos-macros/i8577f/Macro_1.scala @@ -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})) } diff --git a/tests/pos-macros/i8577f/Main_2.scala b/tests/pos-macros/i8577f/Main_2.scala new file mode 100644 index 000000000000..fd1bb3e6186f --- /dev/null +++ b/tests/pos-macros/i8577f/Main_2.scala @@ -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")) diff --git a/tests/pos-macros/i8577g/Macro_1.scala b/tests/pos-macros/i8577g/Macro_1.scala new file mode 100644 index 000000000000..2da12d6e23fd --- /dev/null +++ b/tests/pos-macros/i8577g/Macro_1.scala @@ -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})) } diff --git a/tests/pos-macros/i8577g/Main_2.scala b/tests/pos-macros/i8577g/Main_2.scala new file mode 100644 index 000000000000..4998b9962802 --- /dev/null +++ b/tests/pos-macros/i8577g/Main_2.scala @@ -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) diff --git a/tests/pos-macros/i8577h/Macro_1.scala b/tests/pos-macros/i8577h/Macro_1.scala new file mode 100644 index 000000000000..2da12d6e23fd --- /dev/null +++ b/tests/pos-macros/i8577h/Macro_1.scala @@ -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})) } diff --git a/tests/pos-macros/i8577h/Main_2.scala b/tests/pos-macros/i8577h/Main_2.scala new file mode 100644 index 000000000000..9fe2565a0ec3 --- /dev/null +++ b/tests/pos-macros/i8577h/Main_2.scala @@ -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) diff --git a/tests/run/i8577a.scala b/tests/run/i8577a.scala new file mode 100644 index 000000000000..fa9d23cb928a --- /dev/null +++ b/tests/run/i8577a.scala @@ -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) diff --git a/tests/run/i8577b.scala b/tests/run/i8577b.scala new file mode 100644 index 000000000000..91744cf48527 --- /dev/null +++ b/tests/run/i8577b.scala @@ -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) diff --git a/tests/run/i8577c.scala b/tests/run/i8577c.scala new file mode 100644 index 000000000000..e49743306ce4 --- /dev/null +++ b/tests/run/i8577c.scala @@ -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) diff --git a/tests/run/i8577d.scala b/tests/run/i8577d.scala new file mode 100644 index 000000000000..8af8fad7cd56 --- /dev/null +++ b/tests/run/i8577d.scala @@ -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) diff --git a/tests/run/i8577e.scala b/tests/run/i8577e.scala new file mode 100644 index 000000000000..89d391ded2fd --- /dev/null +++ b/tests/run/i8577e.scala @@ -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")) diff --git a/tests/run/i8577f.scala b/tests/run/i8577f.scala new file mode 100644 index 000000000000..6ddaedc7b39f --- /dev/null +++ b/tests/run/i8577f.scala @@ -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) diff --git a/tests/run/i8577g.scala b/tests/run/i8577g.scala new file mode 100644 index 000000000000..ec5019d4c353 --- /dev/null +++ b/tests/run/i8577g.scala @@ -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) diff --git a/tests/run/i8577h.scala b/tests/run/i8577h.scala new file mode 100644 index 000000000000..457c8138d840 --- /dev/null +++ b/tests/run/i8577h.scala @@ -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) diff --git a/tests/run/i8577i.scala b/tests/run/i8577i.scala new file mode 100644 index 000000000000..1893425b8782 --- /dev/null +++ b/tests/run/i8577i.scala @@ -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)