From 8bc5e73e5a62e7aa46f4ee249250bb496d6583f6 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 01/10] fix bug with inline extension methods --- compiler/src/dotty/tools/dotc/typer/Inliner.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index fd8e86897f49..b7441c7c996c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -205,6 +205,7 @@ object Inliner { case _ => Nil val unapplyInfo = sym.info match case info: PolyType => info.instantiate(targs.map(_.tpe)) + case MethodTpe(_, _, rest) if sym.flags.is(ExtensionMethod) => rest case info => info val unappplySym = newSymbol(cls, sym.name.toTermName, Synthetic | Method, unapplyInfo, coord = sym.coord).entered From bc8dc65fd51718ddc6c82057eeaaffd359393695 Mon Sep 17 00:00:00 2001 From: gorilskij <43991400@users.noreply.github.com> Date: Wed, 27 Apr 2022 21:38:28 +0200 Subject: [PATCH 02/10] special-case inline extension unapplySeq (including polymorphic variants) --- compiler/src/dotty/tools/dotc/typer/Inliner.scala | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index b7441c7c996c..5724c948cd72 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -203,9 +203,15 @@ object Inliner { val targs = fun match case TypeApply(_, targs) => targs case _ => Nil + val unapplyInfo = sym.info match - case info: PolyType => info.instantiate(targs.map(_.tpe)) - case MethodTpe(_, _, rest) if sym.flags.is(ExtensionMethod) => rest + case info: PolyType => info.instantiate(targs.map(_.tpe)) match + case MethodTpe(_, _, rt: PolyType) => rt.instantiate(targs.map(_.tpe)) + case MethodTpe(_, _, rt) if sym.flags.is(ExtensionMethod) => rt + case info => info + + case MethodTpe(_, _, rt: PolyType) => rt.instantiate(targs.map(_.tpe)) + case MethodTpe(_, _, rt) if sym.flags.is(ExtensionMethod) => rt case info => info val unappplySym = newSymbol(cls, sym.name.toTermName, Synthetic | Method, unapplyInfo, coord = sym.coord).entered From 99873a2bacf21a91d5e2e9e32155e9959dd163b8 Mon Sep 17 00:00:00 2001 From: gorilskij <43991400@users.noreply.github.com> Date: Tue, 3 May 2022 12:27:53 +0200 Subject: [PATCH 03/10] comment uncertain line --- compiler/src/dotty/tools/dotc/typer/Inliner.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 4db7924994a5..a160bfc30a48 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -210,6 +210,9 @@ object Inliner { val targs = fun match case TypeApply(_, targs) => targs + // TODO: understand +// case Apply(TypeApply(_, targs), _) => targs + // === case _ => Nil val unapplyInfo = sym.info match @@ -217,7 +220,6 @@ object Inliner { case MethodTpe(_, _, rt: PolyType) => rt.instantiate(targs.map(_.tpe)) case MethodTpe(_, _, rt) if sym.flags.is(ExtensionMethod) => rt case info => info - case MethodTpe(_, _, rt: PolyType) => rt.instantiate(targs.map(_.tpe)) case MethodTpe(_, _, rt) if sym.flags.is(ExtensionMethod) => rt case info => info From c0439c3d30824f3291a3539025678cd453577bc4 Mon Sep 17 00:00:00 2001 From: gorilskij <43991400@users.noreply.github.com> Date: Tue, 3 May 2022 16:48:01 +0200 Subject: [PATCH 04/10] fix another bug --- compiler/src/dotty/tools/dotc/typer/Inliner.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index a160bfc30a48..a58d1189f905 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -210,8 +210,8 @@ object Inliner { val targs = fun match case TypeApply(_, targs) => targs - // TODO: understand -// case Apply(TypeApply(_, targs), _) => targs + // TODO: separate issue + case Apply(TypeApply(_, targs), _) => targs // === case _ => Nil From 11a3f9faf6b2bb4fed86bec570d354ae4a825cd3 Mon Sep 17 00:00:00 2001 From: gorilskij <43991400@users.noreply.github.com> Date: Tue, 3 May 2022 17:24:49 +0200 Subject: [PATCH 05/10] add test case --- .../src/dotty/tools/dotc/typer/Inliner.scala | 12 +- tests/pos/i8577.scala | 169 ++++++++++++++++++ 2 files changed, 174 insertions(+), 7 deletions(-) create mode 100644 tests/pos/i8577.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 4db7924994a5..3ab7f5a895c0 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -196,7 +196,7 @@ object Inliner { // as its right hand side. The call to the wrapper unapply serves as the signpost for pattern matching. // After pattern matching, the anonymous class is removed in phase InlinePatterns with a beta reduction step. // - // An inline unapply `P.unapply` in a plattern `P(x1,x2,...)` is transformed into + // An inline unapply `P.unapply` in a pattern `P(x1,x2,...)` is transformed into // `{ class $anon { def unapply(t0: T0)(using t1: T1, t2: T2, ...): R = P.unapply(t0)(using t1, t2, ...) }; new $anon }.unapply` // and the call `P.unapply(x1, x2, ...)` is inlined. // This serves as a placeholder for the inlined body until the `patternMatcher` phase. After pattern matcher @@ -211,24 +211,22 @@ object Inliner { val targs = fun match case TypeApply(_, targs) => targs case _ => Nil - val unapplyInfo = sym.info match case info: PolyType => info.instantiate(targs.map(_.tpe)) match case MethodTpe(_, _, rt: PolyType) => rt.instantiate(targs.map(_.tpe)) case MethodTpe(_, _, rt) if sym.flags.is(ExtensionMethod) => rt case info => info - case MethodTpe(_, _, rt: PolyType) => rt.instantiate(targs.map(_.tpe)) case MethodTpe(_, _, rt) if sym.flags.is(ExtensionMethod) => rt 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, unapplyInfo, 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) } diff --git a/tests/pos/i8577.scala b/tests/pos/i8577.scala new file mode 100644 index 000000000000..0fa5076b9bb3 --- /dev/null +++ b/tests/pos/i8577.scala @@ -0,0 +1,169 @@ +def main: Unit = { + { + object A1: + def unapplySeq(x: Int) = Some(Seq(x)) + + val A1(x) = 1 + println(s"A1: $x") + } + + { + object A2: + def unapplySeq[T](x: T) = Some(Seq(x)) + + val A2(x) = 2 + println(s"A2: $x") + } + + { + object B1: + inline def unapplySeq(x: Int) = Some(Seq(x)) + + val B1(x) = 3 + println(s"B1: $x") + } + + { + object B2: + inline def unapplySeq[T](x: T) = Some(Seq(x)) + + val B2(x) = 4 + println(s"B2: $x") + } + + { + object C1: + inline def unapplySeq(inline x: Int) = Some(Seq(x)) + + val C1(x) = 5 + println(s"C1: $x") + } + + { + object C2: + inline def unapplySeq[T](inline x: T) = Some(Seq(x)) + + val C2(x) = 6 + println(s"C2: $x") + } + + { + object D1 + extension (o: D1.type) def unapplySeq(x: Int) = Some(Seq(x)) + + val D1(x) = 7 + println(s"D1: $x") + } + + { + object D2 + extension (o: D2.type) def unapplySeq[T](x: T) = Some(Seq(x)) + + val D2(x) = 8 + println(s"D2: $x") + } + + { + object D3 + extension [T] (o: D3.type) def unapplySeq(x: T) = Some(Seq(x)) + + val D3(x) = 9 + println(s"D3: $x") + } + + { + object D4 + extension [T] (o: D4.type) def unapplySeq[U](x: T | U) = Some(Seq(x)) + + val D4(x) = 10 + println(s"D4: $x") + } + + { + object E1 + extension (o: E1.type) inline def unapplySeq(x: Int) = Some(Seq(x)) + + val E1(x) = 11 + println(s"E1: $x") + } + + { + object E2 + extension (o: E2.type) inline def unapplySeq[T](x: T) = Some(Seq(x)) + + val E2(x) = 12 + println(s"E2: $x") + } + + { + object E4b + extension [T] (o: E4b.type) inline def unapplySeq[U](x: U) = Some(Seq(x)) + + val E4b(x) = 14.2 + println(s"E4b: $x") + } + + { + object F1 + extension (o: F1.type) inline def unapplySeq(inline x: Int) = Some(Seq(x)) + + val F1(x) = 15 + println(s"F1: $x") + } + + { + object F2 + extension (o: F2.type) inline def unapplySeq[T](inline x: T) = Some(Seq(x)) + + val F2(x) = 16 + println(s"F2: $x") + } + + { + object F4b + extension [T] (o: F4b.type) inline def unapplySeq[U](inline x: U) = Some(Seq(x)) + + val F4b(x) = 18.2 + println(s"F4b: $x") + } + + { + object F4d + extension [T] (o: F4d.type) inline def unapplySeq[U](inline x: (T, U)) = Some(Seq(x)) + + val F4d(x) = (18.4, 18.5) + println(s"F4d: $x") + } + + { + object G1 + extension (inline o: G1.type) inline def unapplySeq(x: Int) = Some(Seq(x)) + + val G1(x) = 19 + println(s"G1: $x") + } + + { + object G2 + extension (inline o: G2.type) inline def unapplySeq[T](x: T) = Some(Seq(x)) + + val G2(x) = 20 + println(s"G2: $x") + } + + { + object H1 + extension (inline o: H1.type) inline def unapplySeq(inline x: Int) = Some(Seq(x)) + + val H1(x) = 23 + println(s"H1: $x") + } + + { + object H2 + extension (inline o: H2.type) inline def unapplySeq[T](inline x: T) = Some(Seq(x)) + + val H2(x) = 24 + println(s"H2: $x") + } +} From 04bd41e69843f7ef7e6ff4553610a417eea8aca3 Mon Sep 17 00:00:00 2001 From: gorilskij <43991400@users.noreply.github.com> Date: Wed, 4 May 2022 09:32:01 +0200 Subject: [PATCH 06/10] add (non-working) macro test case --- tests/pos/i8577.scala | 169 ----------------------------------- tests/pos/i8577/MacroA.scala | 16 ++++ tests/pos/i8577/Main.scala | 132 +++++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 169 deletions(-) delete mode 100644 tests/pos/i8577.scala create mode 100644 tests/pos/i8577/MacroA.scala create mode 100644 tests/pos/i8577/Main.scala diff --git a/tests/pos/i8577.scala b/tests/pos/i8577.scala deleted file mode 100644 index 0fa5076b9bb3..000000000000 --- a/tests/pos/i8577.scala +++ /dev/null @@ -1,169 +0,0 @@ -def main: Unit = { - { - object A1: - def unapplySeq(x: Int) = Some(Seq(x)) - - val A1(x) = 1 - println(s"A1: $x") - } - - { - object A2: - def unapplySeq[T](x: T) = Some(Seq(x)) - - val A2(x) = 2 - println(s"A2: $x") - } - - { - object B1: - inline def unapplySeq(x: Int) = Some(Seq(x)) - - val B1(x) = 3 - println(s"B1: $x") - } - - { - object B2: - inline def unapplySeq[T](x: T) = Some(Seq(x)) - - val B2(x) = 4 - println(s"B2: $x") - } - - { - object C1: - inline def unapplySeq(inline x: Int) = Some(Seq(x)) - - val C1(x) = 5 - println(s"C1: $x") - } - - { - object C2: - inline def unapplySeq[T](inline x: T) = Some(Seq(x)) - - val C2(x) = 6 - println(s"C2: $x") - } - - { - object D1 - extension (o: D1.type) def unapplySeq(x: Int) = Some(Seq(x)) - - val D1(x) = 7 - println(s"D1: $x") - } - - { - object D2 - extension (o: D2.type) def unapplySeq[T](x: T) = Some(Seq(x)) - - val D2(x) = 8 - println(s"D2: $x") - } - - { - object D3 - extension [T] (o: D3.type) def unapplySeq(x: T) = Some(Seq(x)) - - val D3(x) = 9 - println(s"D3: $x") - } - - { - object D4 - extension [T] (o: D4.type) def unapplySeq[U](x: T | U) = Some(Seq(x)) - - val D4(x) = 10 - println(s"D4: $x") - } - - { - object E1 - extension (o: E1.type) inline def unapplySeq(x: Int) = Some(Seq(x)) - - val E1(x) = 11 - println(s"E1: $x") - } - - { - object E2 - extension (o: E2.type) inline def unapplySeq[T](x: T) = Some(Seq(x)) - - val E2(x) = 12 - println(s"E2: $x") - } - - { - object E4b - extension [T] (o: E4b.type) inline def unapplySeq[U](x: U) = Some(Seq(x)) - - val E4b(x) = 14.2 - println(s"E4b: $x") - } - - { - object F1 - extension (o: F1.type) inline def unapplySeq(inline x: Int) = Some(Seq(x)) - - val F1(x) = 15 - println(s"F1: $x") - } - - { - object F2 - extension (o: F2.type) inline def unapplySeq[T](inline x: T) = Some(Seq(x)) - - val F2(x) = 16 - println(s"F2: $x") - } - - { - object F4b - extension [T] (o: F4b.type) inline def unapplySeq[U](inline x: U) = Some(Seq(x)) - - val F4b(x) = 18.2 - println(s"F4b: $x") - } - - { - object F4d - extension [T] (o: F4d.type) inline def unapplySeq[U](inline x: (T, U)) = Some(Seq(x)) - - val F4d(x) = (18.4, 18.5) - println(s"F4d: $x") - } - - { - object G1 - extension (inline o: G1.type) inline def unapplySeq(x: Int) = Some(Seq(x)) - - val G1(x) = 19 - println(s"G1: $x") - } - - { - object G2 - extension (inline o: G2.type) inline def unapplySeq[T](x: T) = Some(Seq(x)) - - val G2(x) = 20 - println(s"G2: $x") - } - - { - object H1 - extension (inline o: H1.type) inline def unapplySeq(inline x: Int) = Some(Seq(x)) - - val H1(x) = 23 - println(s"H1: $x") - } - - { - object H2 - extension (inline o: H2.type) inline def unapplySeq[T](inline x: T) = Some(Seq(x)) - - val H2(x) = 24 - println(s"H2: $x") - } -} diff --git a/tests/pos/i8577/MacroA.scala b/tests/pos/i8577/MacroA.scala new file mode 100644 index 000000000000..04996a7adc99 --- /dev/null +++ b/tests/pos/i8577/MacroA.scala @@ -0,0 +1,16 @@ +package i8577 + +import scala.quoted._ + +object MacroA: + opaque type SC = scala.StringContext + def apply(ctx: scala.StringContext): SC = ctx + def unapply(ctx: SC): Option[scala.StringContext] = Some(ctx) + +extension (ctx: StringContext) def mac: MacroA.SC = MacroA(ctx) +extension (inline ctx: MacroA.SC) inline def apply(inline args: Int*): String = "" +extension (inline ctx: MacroA.SC) inline def unapplySeq(inline input: Int): Option[Seq[Int]] = + ${ implUnapply('ctx, 'input) } + +def implUnapply(sc: Expr[MacroA.SC], input: Expr[Int])(using Quotes): Expr[Option[Seq[Int]]] = + Expr(Some(Seq(0))) diff --git a/tests/pos/i8577/Main.scala b/tests/pos/i8577/Main.scala new file mode 100644 index 000000000000..fee378a3fb21 --- /dev/null +++ b/tests/pos/i8577/Main.scala @@ -0,0 +1,132 @@ +package i8577 + +def main: Unit = { + { + 1 match + case mac"$x" => x + } +} + + + + + + + + + + + + + + + + + + + + + + + + + +// { +// // B +// object F2 +// extension (o: F2.type) inline def unapplySeq[T](inline x: T) = Some(Seq(x)) +// +// val F2(x) = 16 +// println(s"F2: $x") +// } +// +// { +// // C +// object F1 +// extension [T] (o: F1.type) inline def unapplySeq(inline x: T) = Some(Seq(x)) +// +// val F1(x) = 15 +// println(s"F1: $x") +// } +// +// { +// // D +// object F4b +// extension [T] (o: F4b.type) inline def unapplySeq[U](inline x: T) = Some(Seq(x)) +// +// val F4b(x) = 18.2 +// println(s"F4b: $x") +// } +// +// { +// // E +// object F4b +// extension [T] (o: F4b.type) inline def unapplySeq[U](inline x: U) = Some(Seq(x)) +// +// val F4b(x) = 18.2 +// println(s"F4b: $x") +// } +// +// { +// // F +// object F4d +// extension [T] (o: F4d.type) inline def unapplySeq[U](inline x: (T, U)) = Some(Seq(x)) +// +// val F4d(x) = (18.4, 18.5) +// println(s"F4d: $x") +// } +// +// { +// // G +// object H1 +// extension (inline o: H1.type) inline def unapplySeq(inline x: Int) = Some(Seq(x)) +// +// val H1(x) = 23 +// println(s"H1: $x") +// } +// +// { +// // H +// object H2 +// extension (inline o: H2.type) inline def unapplySeq[T](inline x: T) = Some(Seq(x)) +// +// val H2(x) = 24 +// println(s"H2: $x") +// } +// +// { +// // I +// object H2 +// extension [T] (inline o: H2.type) inline def unapplySeq(inline x: T) = Some(Seq(x)) +// +// val H2(x) = 24 +// println(s"H2: $x") +// } +// +// { +// // J +// object H2 +// extension [T] (inline o: H2.type) inline def unapplySeq[U](inline x: T) = Some(Seq(x)) +// +// val H2(x) = 24 +// println(s"H2: $x") +// } +// +// { +// // K +// object H2 +// extension [T] (inline o: H2.type) inline def unapplySeq[U](inline x: U) = Some(Seq(x)) +// +// val H2(x) = 24 +// println(s"H2: $x") +// } +// +// { +// // L +// object H2 +// extension [T] (inline o: H2.type) inline def unapplySeq[U](inline x: (T, U)) = Some(Seq(x)) +// +// val H2(x) = (24, "a") +// println(s"H2: $x") +// } +//} From ea9b46fad897fa5d196863651b45db39a3887ae9 Mon Sep 17 00:00:00 2001 From: gorilskij <43991400@users.noreply.github.com> Date: Wed, 4 May 2022 11:55:34 +0200 Subject: [PATCH 07/10] add proper test cases --- tests/pos/i8577/MacroA.scala | 16 ----- tests/pos/i8577/MacroA_1.scala | 12 ++++ tests/pos/i8577/MacroB_1.scala | 12 ++++ tests/pos/i8577/MacroC_1.scala | 12 ++++ tests/pos/i8577/MacroD_1.scala | 12 ++++ tests/pos/i8577/MacroE_1.scala | 12 ++++ tests/pos/i8577/MacroF_1.scala | 12 ++++ tests/pos/i8577/MacroG_1.scala | 12 ++++ tests/pos/i8577/{Main.scala => Main_2.scala} | 61 +++++++++++++++----- 9 files changed, 131 insertions(+), 30 deletions(-) delete mode 100644 tests/pos/i8577/MacroA.scala create mode 100644 tests/pos/i8577/MacroA_1.scala create mode 100644 tests/pos/i8577/MacroB_1.scala create mode 100644 tests/pos/i8577/MacroC_1.scala create mode 100644 tests/pos/i8577/MacroD_1.scala create mode 100644 tests/pos/i8577/MacroE_1.scala create mode 100644 tests/pos/i8577/MacroF_1.scala create mode 100644 tests/pos/i8577/MacroG_1.scala rename tests/pos/i8577/{Main.scala => Main_2.scala} (51%) diff --git a/tests/pos/i8577/MacroA.scala b/tests/pos/i8577/MacroA.scala deleted file mode 100644 index 04996a7adc99..000000000000 --- a/tests/pos/i8577/MacroA.scala +++ /dev/null @@ -1,16 +0,0 @@ -package i8577 - -import scala.quoted._ - -object MacroA: - opaque type SC = scala.StringContext - def apply(ctx: scala.StringContext): SC = ctx - def unapply(ctx: SC): Option[scala.StringContext] = Some(ctx) - -extension (ctx: StringContext) def mac: MacroA.SC = MacroA(ctx) -extension (inline ctx: MacroA.SC) inline def apply(inline args: Int*): String = "" -extension (inline ctx: MacroA.SC) inline def unapplySeq(inline input: Int): Option[Seq[Int]] = - ${ implUnapply('ctx, 'input) } - -def implUnapply(sc: Expr[MacroA.SC], input: Expr[Int])(using Quotes): Expr[Option[Seq[Int]]] = - Expr(Some(Seq(0))) diff --git a/tests/pos/i8577/MacroA_1.scala b/tests/pos/i8577/MacroA_1.scala new file mode 100644 index 000000000000..1a147038adce --- /dev/null +++ b/tests/pos/i8577/MacroA_1.scala @@ -0,0 +1,12 @@ +package i8577 + +import scala.quoted._ + +object MacroA: + opaque type StringContext = scala.StringContext + def apply(ctx: scala.StringContext): StringContext = ctx + def unapply(ctx: StringContext): Option[scala.StringContext] = Some(ctx) + +def implUnapplyA(sc: Expr[MacroB.StringContext], input: Expr[Int]) + (using Quotes): Expr[Option[Seq[Int]]] = + '{ Some(Seq(${input})) } diff --git a/tests/pos/i8577/MacroB_1.scala b/tests/pos/i8577/MacroB_1.scala new file mode 100644 index 000000000000..e5b4ee5b5c66 --- /dev/null +++ b/tests/pos/i8577/MacroB_1.scala @@ -0,0 +1,12 @@ +package i8577 + +import scala.quoted._ + +object MacroB: + opaque type StringContext = scala.StringContext + def apply(ctx: scala.StringContext): StringContext = ctx + def unapply(ctx: StringContext): Option[scala.StringContext] = Some(ctx) + +def implUnapplyB[U](sc: Expr[MacroB.StringContext], input: Expr[U]) + (using Type[U])(using Quotes): Expr[Option[Seq[U]]] = + '{ Some(Seq(${input})) } diff --git a/tests/pos/i8577/MacroC_1.scala b/tests/pos/i8577/MacroC_1.scala new file mode 100644 index 000000000000..be7047cb3527 --- /dev/null +++ b/tests/pos/i8577/MacroC_1.scala @@ -0,0 +1,12 @@ +package i8577 + +import scala.quoted._ + +object MacroC: + opaque type StringContext = scala.StringContext + def apply(ctx: scala.StringContext): StringContext = ctx + def unapply(ctx: StringContext): Option[scala.StringContext] = Some(ctx) + +def implUnapplyC[T](sc: Expr[MacroC.StringContext], input: Expr[T]) + (using Type[T])(using Quotes): Expr[Option[Seq[T]]] = + '{ Some(Seq(${input})) } diff --git a/tests/pos/i8577/MacroD_1.scala b/tests/pos/i8577/MacroD_1.scala new file mode 100644 index 000000000000..53184da3fc3a --- /dev/null +++ b/tests/pos/i8577/MacroD_1.scala @@ -0,0 +1,12 @@ +package i8577 + +import scala.quoted._ + +object MacroD: + opaque type StringContext = scala.StringContext + def apply(ctx: scala.StringContext): StringContext = ctx + def unapply(ctx: StringContext): Option[scala.StringContext] = Some(ctx) + +def implUnapplyD[T, U](sc: Expr[MacroD.StringContext], input: Expr[T]) + (using Type[T])(using Quotes): Expr[Option[Seq[T]]] = + '{ Some(Seq(${input})) } diff --git a/tests/pos/i8577/MacroE_1.scala b/tests/pos/i8577/MacroE_1.scala new file mode 100644 index 000000000000..3351e3329c65 --- /dev/null +++ b/tests/pos/i8577/MacroE_1.scala @@ -0,0 +1,12 @@ +package i8577 + +import scala.quoted._ + +object MacroE: + opaque type StringContext = scala.StringContext + def apply(ctx: scala.StringContext): StringContext = ctx + def unapply(ctx: StringContext): Option[scala.StringContext] = Some(ctx) + +def implUnapplyE[T, U](sc: Expr[MacroE.StringContext], input: Expr[U]) + (using Type[U])(using Quotes): Expr[Option[Seq[U]]] = + '{ Some(Seq(${input})) } diff --git a/tests/pos/i8577/MacroF_1.scala b/tests/pos/i8577/MacroF_1.scala new file mode 100644 index 000000000000..ebe01cbbacd7 --- /dev/null +++ b/tests/pos/i8577/MacroF_1.scala @@ -0,0 +1,12 @@ +package i8577 + +import scala.quoted._ + +object MacroF: + opaque type StringContext = scala.StringContext + def apply(ctx: scala.StringContext): StringContext = ctx + def unapply(ctx: StringContext): Option[scala.StringContext] = Some(ctx) + +def implUnapplyF[T, U](sc: Expr[MacroF.StringContext], input: Expr[(T, U)]) + (using Type[T], Type[U])(using Quotes): Expr[Option[Seq[(T, U)]]] = + '{ Some(Seq(${input})) } diff --git a/tests/pos/i8577/MacroG_1.scala b/tests/pos/i8577/MacroG_1.scala new file mode 100644 index 000000000000..4324b553a7c1 --- /dev/null +++ b/tests/pos/i8577/MacroG_1.scala @@ -0,0 +1,12 @@ +package i8577 + +import scala.quoted._ + +object MacroG: + opaque type StringContext = scala.StringContext + def apply(ctx: scala.StringContext): StringContext = ctx + def unapply(ctx: StringContext): Option[scala.StringContext] = Some(ctx) + +def implUnapplyG[T, U](sc: Expr[MacroG.StringContext], input: Expr[T | U]) + (using Type[T], Type[U])(using Quotes): Expr[Option[Seq[T | U]]] = + '{ Some(Seq(${input})) } diff --git a/tests/pos/i8577/Main.scala b/tests/pos/i8577/Main_2.scala similarity index 51% rename from tests/pos/i8577/Main.scala rename to tests/pos/i8577/Main_2.scala index fee378a3fb21..ad10ee19bfcd 100644 --- a/tests/pos/i8577/Main.scala +++ b/tests/pos/i8577/Main_2.scala @@ -2,34 +2,67 @@ package i8577 def main: Unit = { { - 1 match - case mac"$x" => x - } -} - - - - - - - - - - + extension (ctx: StringContext) def macroA: MacroB.StringContext = MacroB(ctx) + extension (inline ctx: MacroB.StringContext) inline def unapplySeq(inline input: Int): Option[Seq[Int]] = + ${implUnapplyA('ctx, 'input)} + val macroA"$xA" = 1 + } + { + extension (ctx: StringContext) def macroB: MacroB.StringContext = MacroB(ctx) + extension (inline ctx: MacroB.StringContext) inline def unapplySeq[U](inline input: U): Option[Seq[U]] = + ${ implUnapplyB('ctx, 'input) } + val macroB"$xB" = 2 + } + { + extension (ctx: StringContext) def macroC: MacroC.StringContext = MacroC(ctx) + extension [T] (inline ctx: MacroC.StringContext) inline def unapplySeq(inline input: T): Option[Seq[T]] = + ${ implUnapplyC('ctx, 'input) } + // compiler error +// val macroC"$xC" = 3 + } + { + extension (ctx: StringContext) def macroD: MacroD.StringContext = MacroD(ctx) + extension [T] (inline ctx: MacroD.StringContext) inline def unapplySeq[U](inline input: T): Option[Seq[T]] = + ${ implUnapplyD('ctx, 'input) } + // miscompilation +// val macroD"$xD" = 4 + } + { + extension (ctx: StringContext) def macroE: MacroE.StringContext = MacroE(ctx) + extension [T] (inline ctx: MacroE.StringContext) inline def unapplySeq[U](inline input: U): Option[Seq[U]] = + ${ implUnapplyE('ctx, 'input) } + val macroE"$xE" = 5 + } + { + extension (ctx: StringContext) def macroF: MacroF.StringContext = MacroF(ctx) + extension [T] (inline ctx: MacroF.StringContext) inline def unapplySeq[U](inline input: (T, U)): Option[Seq[(T, U)]] = + ${ implUnapplyF('ctx, 'input) } + val macroF"$xF" = (6, 7) + // miscompilation +// val macroF"$xF" = (6, "7") + } + { + extension (ctx: StringContext) def macroG: MacroG.StringContext = MacroG(ctx) + extension [T] (inline ctx: MacroG.StringContext) inline def unapplySeq[U](inline input: T | U): Option[Seq[T | U]] = + ${ implUnapplyG('ctx, 'input) } + // compiler error +// val macroG"$xG" = 8 + } +} // { // // B From 2c6e613650da47a6e3eb11e7b5c54d658ec7b885 Mon Sep 17 00:00:00 2001 From: gorilskij <43991400@users.noreply.github.com> Date: Wed, 4 May 2022 13:00:10 +0200 Subject: [PATCH 08/10] minor change --- tests/pos/i8577/MacroD_1.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pos/i8577/MacroD_1.scala b/tests/pos/i8577/MacroD_1.scala index 53184da3fc3a..3e8d6df54484 100644 --- a/tests/pos/i8577/MacroD_1.scala +++ b/tests/pos/i8577/MacroD_1.scala @@ -7,6 +7,6 @@ object MacroD: def apply(ctx: scala.StringContext): StringContext = ctx def unapply(ctx: StringContext): Option[scala.StringContext] = Some(ctx) -def implUnapplyD[T, U](sc: Expr[MacroD.StringContext], input: Expr[T]) +def implUnapplyD[T](sc: Expr[MacroD.StringContext], input: Expr[T]) (using Type[T])(using Quotes): Expr[Option[Seq[T]]] = '{ Some(Seq(${input})) } From 26e4dcaf5aa65cb45bb8e788308dd4ba54582676 Mon Sep 17 00:00:00 2001 From: gorilskij <43991400@users.noreply.github.com> Date: Sat, 7 May 2022 13:59:13 +0200 Subject: [PATCH 09/10] implement a fix --- compiler/src/dotty/tools/dotc/typer/Inliner.scala | 1 + tests/pos/i8577/Main_2.scala | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 3ab7f5a895c0..4a06ee3ce07c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -210,6 +210,7 @@ object Inliner { val targs = fun match case TypeApply(_, targs) => targs + case Apply(TypeApply(_, targs), _) => targs case _ => Nil val unapplyInfo = sym.info match case info: PolyType => info.instantiate(targs.map(_.tpe)) match diff --git a/tests/pos/i8577/Main_2.scala b/tests/pos/i8577/Main_2.scala index ad10ee19bfcd..051ac91503fc 100644 --- a/tests/pos/i8577/Main_2.scala +++ b/tests/pos/i8577/Main_2.scala @@ -23,7 +23,7 @@ def main: Unit = { ${ implUnapplyC('ctx, 'input) } // compiler error -// val macroC"$xC" = 3 + val macroC"$xC" = 3 } { From e9965a1a44fbe5946c3ce091746c07095e6b19ac Mon Sep 17 00:00:00 2001 From: gorilskij <43991400@users.noreply.github.com> Date: Sat, 14 May 2022 11:58:50 +0200 Subject: [PATCH 10/10] uncomment relevant test case --- tests/pos/i8577/Main_2.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/pos/i8577/Main_2.scala b/tests/pos/i8577/Main_2.scala index 051ac91503fc..43c818237689 100644 --- a/tests/pos/i8577/Main_2.scala +++ b/tests/pos/i8577/Main_2.scala @@ -22,7 +22,6 @@ def main: Unit = { extension [T] (inline ctx: MacroC.StringContext) inline def unapplySeq(inline input: T): Option[Seq[T]] = ${ implUnapplyC('ctx, 'input) } - // compiler error val macroC"$xC" = 3 }