diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index f94eac90f037..18bb3a40cf12 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -1439,6 +1439,8 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler end UnapplyTypeTest object Unapply extends UnapplyModule: + def apply(fun: Term, implicits: List[Term], patterns: List[Tree]): Unapply = + withDefaultPos(tpd.UnApply(fun, implicits, patterns, dotc.core.Symbols.defn.NothingType)) def copy(original: Tree)(fun: Term, implicits: List[Term], patterns: List[Tree]): Unapply = withDefaultPos(tpd.cpy.UnApply(original)(fun, implicits, patterns)) def unapply(x: Unapply): (Term, List[Term], List[Tree]) = diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index d8f1c431a651..b2907873d4fb 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -2087,7 +2087,11 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** Methods of the module object `val Unapply` */ trait UnapplyModule { this: Unapply.type => + /** Create an `Unapply` tree representing a pattern `()(using )` */ + def apply(fun: Term, implicits: List[Term], patterns: List[Tree]): Unapply + /** Copy an `Unapply` tree representing a pattern `()(using )` */ def copy(original: Tree)(fun: Term, implicits: List[Term], patterns: List[Tree]): Unapply + /** Matches an `Unapply(fun, implicits, patterns)` tree representing a pattern `()(using )` */ def unapply(x: Unapply): (Term, List[Term], List[Tree]) } @@ -2097,8 +2101,15 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** Extension methods of `Unapply` */ trait UnapplyMethods: extension (self: Unapply) + /** The extractor function of the pattern. + * + * It may be a reference to the `unapply` method of the pattern or may be a + * partially applied tree containing type parameters and leading given parameters. + */ def fun: Term + /** Training implicit parameters of the `unapply` method */ def implicits: List[Term] + /** List of nested patterns */ def patterns: List[Tree] end extension end UnapplyMethods diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index c4d52097eba8..050e20ac6fbb 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -11,5 +11,7 @@ object MiMaFilters { exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.getJPath"), exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.name"), exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.path"), + exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#UnapplyModule.apply"), + exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#UnapplyModule.apply"), ) } diff --git a/tests/pos-macros/i12850/Macros_1.scala b/tests/pos-macros/i12850/Macros_1.scala new file mode 100644 index 000000000000..a54bff9b12c2 --- /dev/null +++ b/tests/pos-macros/i12850/Macros_1.scala @@ -0,0 +1,19 @@ + +import scala.quoted.* + +inline def foo() = ${ expr } + +private def expr(using Quotes): Expr[Unit] = + import quotes.reflect.* + + // Option(1) match + // case Some(1) => () + // case None => () + val mtch2 = Match( + Apply(TypeApply(Ref(Symbol.requiredMethod("scala.Option.apply")), List(Inferred(TypeRepr.of[Int]))), List(Literal(IntConstant(1)))), + List( + CaseDef(/** FIXME: needs TypedTree from #12200; remove cast */Typed(Unapply(TypeApply(Ref(Symbol.requiredMethod("scala.Some.unapply")), List(Inferred(TypeRepr.of[Int]))), Nil, List(Literal(IntConstant(1)))).asInstanceOf[Term], Inferred(TypeRepr.of[Some[Int]])), None, Literal(UnitConstant())), + CaseDef(Ref(Symbol.requiredModule("scala.None")), None, Literal(UnitConstant()))) + ) + + mtch2.asExprOf[Unit] diff --git a/tests/pos-macros/i12850/Test_2.scala b/tests/pos-macros/i12850/Test_2.scala new file mode 100644 index 000000000000..08152921e268 --- /dev/null +++ b/tests/pos-macros/i12850/Test_2.scala @@ -0,0 +1 @@ +def test = foo()