From 776e4d6ba91d7b09fb815c7beb135602f8689b7a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 4 Jul 2022 16:48:19 +0200 Subject: [PATCH] Check is inline unapply has leading implicits We patch the crash in the compiler but do not support this feature yet. To support it see https://github.com/lampepfl/dotty/pull/13158 Fixes #12991 --- compiler/src/dotty/tools/dotc/inlines/Inlines.scala | 12 ++++++++++-- tests/neg/i12991.scala | 7 +++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 tests/neg/i12991.scala diff --git a/compiler/src/dotty/tools/dotc/inlines/Inlines.scala b/compiler/src/dotty/tools/dotc/inlines/Inlines.scala index f62de57722d7..5736bb3b0c2e 100644 --- a/compiler/src/dotty/tools/dotc/inlines/Inlines.scala +++ b/compiler/src/dotty/tools/dotc/inlines/Inlines.scala @@ -185,7 +185,15 @@ object Inlines: // transforms the patterns into terms, the `inlinePatterns` phase removes this anonymous class by β-reducing // the call to the `unapply`. - val UnApply(fun, implicits, patterns) = unapp + object SplitFunAndGivenArgs: + def unapply(tree: Tree): (Tree, List[List[Tree]]) = tree match + case Apply(SplitFunAndGivenArgs(fn, argss), args) => (fn, argss :+ args) + case _ => (tree, Nil) + val UnApply(SplitFunAndGivenArgs(fun, leadingImplicits), trailingImplicits, patterns) = unapp + if leadingImplicits.flatten.nonEmpty then + // To support them see https://github.com/lampepfl/dotty/pull/13158 + report.error("inline unapply methods with given parameters before the scrutinee are not supported", fun) + val sym = unapp.symbol 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 @@ -204,7 +212,7 @@ object Inlines: 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) - cpy.UnApply(unapp)(newFun, implicits, patterns) + cpy.UnApply(unapp)(newFun, trailingImplicits, patterns) end inlinedUnapply /** For a retained inline method, another method that keeps track of diff --git a/tests/neg/i12991.scala b/tests/neg/i12991.scala new file mode 100644 index 000000000000..90e037424c49 --- /dev/null +++ b/tests/neg/i12991.scala @@ -0,0 +1,7 @@ +object Foo: + inline def unapply(using String)(i: Int): Some[Int] = Some(i) + +given String = "" + +val i = 10 match + case Foo(x) => x // error