From c2639f68ab8d27fe0ce964669f57949e718a7400 Mon Sep 17 00:00:00 2001 From: Wojciech Mazur Date: Thu, 13 Aug 2026 18:25:50 +0200 Subject: [PATCH] Fix TupleLambda macros under Scala 3.10 --- .../main/scala/oolong/bson/utils/utils.scala | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/oolong-bson/src/main/scala/oolong/bson/utils/utils.scala b/oolong-bson/src/main/scala/oolong/bson/utils/utils.scala index 509b262..8037eea 100644 --- a/oolong-bson/src/main/scala/oolong/bson/utils/utils.scala +++ b/oolong-bson/src/main/scala/oolong/bson/utils/utils.scala @@ -33,6 +33,29 @@ object AsTerm { object TupleLambda { def unapply(using quotes: Quotes)(expr: Expr[Any]): Option[(String, String)] = import quotes.reflect.* + + object ArrowToLiteral { + def unapply(body: Term): Option[(String, String)] = + body match + // x -> y : Scala 3.9 or earlier + case Apply( + TypeApply(Select(Apply(_, List(Select(_, first))), "->"), _), + List(Literal(StringConstant(second))) + ) => + Some(first -> second) + // Starting with Scala 3.10, inline `->` expands to a typed Tuple2.apply. + // A direct `(field, "name")` is an untyped Apply and remains unsupported. + case Typed( + Apply( + TypeApply(Select(receiver, "apply"), _), + List(Select(_, first), Literal(StringConstant(second))) + ), + _ + ) if receiver.symbol == Symbol.requiredModule("scala.Tuple2") => + Some(first -> second) + case _ => None + } + expr match case AsTerm( Block( @@ -41,12 +64,7 @@ object TupleLambda { "$anonfun", _, _, - Some( - Apply( - TypeApply(Select(Apply(_, List(Select(_, first))), "->"), _), - List(Literal(StringConstant(second))) - ) - ) + Some(ArrowToLiteral(first, second)) ) ), _