Skip to content

Commit 5b2ba2c

Browse files
committed
Handle leading given parameters in inline unapplies
Fixes scala#12991
1 parent 91d11ab commit 5b2ba2c

File tree

2 files changed

+30
-8
lines changed

2 files changed

+30
-8
lines changed

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,19 @@ object Inliner {
183183
// as its right hand side. The call to the wrapper unapply serves as the signpost for pattern matching.
184184
// After pattern matching, the anonymous class is removed in phase InlinePatterns with a beta reduction step.
185185
//
186-
// An inline unapply `P.unapply` in a plattern `P(x1,x2,...)` is transformed into
187-
// `{ class $anon { def unapply(t0: T0)(using t1: T1, t2: T2, ...): R = P.unapply(t0)(using t1, t2, ...) }; new $anon }.unapply`
188-
// and the call `P.unapply(x1, x2, ...)` is inlined.
186+
// An inline unapply `P.unapply` in a pattern `P(using y1,y2,...)(x1,x2,...)` is transformed into
187+
// `{ class $anon { def unapply(using l1: L1, l2: L2, ...)(s: S)(using t1: T1, t2: T2, ...): R = P.unapply(using l1, l2, ...)(s)(using t1, t2, ...) }; new $anon }.unapply(using y1,y2,...)`
188+
// and the call `P.unapply(using l1, l2,...)(x1, x2, ...)(using t1, t2, ...)` is inlined.
189189
// This serves as a placeholder for the inlined body until the `patternMatcher` phase. After pattern matcher
190190
// transforms the patterns into terms, the `inlinePatterns` phase removes this anonymous class by β-reducing
191191
// the call to the `unapply`.
192192

193-
val UnApply(fun, implicits, patterns) = unapp
193+
object SplitFunAndGivenArgs:
194+
def unapply(tree: Tree): (Tree, List[List[Tree]]) = tree match
195+
case Apply(SplitFunAndGivenArgs(fn, argss), args) => (fn, argss :+ args)
196+
case _ => (tree, Nil)
197+
198+
val UnApply(SplitFunAndGivenArgs(fun, givenArgss) , implicits, patterns) = unapp
194199
val sym = unapp.symbol
195200
val cls = newNormalizedClassSymbol(ctx.owner, tpnme.ANON_CLASS, Synthetic | Final, List(defn.ObjectType), coord = sym.coord)
196201
val constr = newConstructor(cls, Synthetic, Nil, Nil, coord = sym.coord).entered
@@ -202,13 +207,15 @@ object Inliner {
202207
case info: PolyType => info.instantiate(targs.map(_.tpe))
203208
case info => info
204209

205-
val unappplySym = newSymbol(cls, sym.name.toTermName, Synthetic | Method, unapplyInfo, coord = sym.coord).entered
206-
val unapply = DefDef(unappplySym, argss =>
207-
inlineCall(fun.appliedToArgss(argss).withSpan(unapp.span))(using ctx.withOwner(unappplySym))
210+
val unapplySym = newSymbol(cls, sym.name.toTermName, Synthetic | Method, unapplyInfo, coord = sym.coord).entered
211+
val unapply = DefDef(unapplySym, argss =>
212+
fun.appliedToArgss(argss).withSpan(unapp.span)
208213
)
214+
209215
val cdef = ClassDef(cls, DefDef(constr), List(unapply))
210216
val newUnapply = Block(cdef :: Nil, New(cls.typeRef, Nil))
211-
val newFun = newUnapply.select(unappplySym).withSpan(unapp.span)
217+
val newFun = newUnapply.select(unapplySym).withSpan(unapp.span).appliedToArgss(givenArgss)
218+
212219
cpy.UnApply(unapp)(newFun, implicits, patterns)
213220
}
214221

tests/pos/i12991.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
object Foo:
2+
inline def unapply(using String)(i: Int): Some[Int] = Some(i)
3+
4+
object Bar:
5+
inline def unapply(using String)(using String)(i: Int): Some[Int] = Some(i)
6+
7+
object Baz:
8+
inline def unapply[T](using String)(i: T): Some[T] = Some(i)
9+
10+
given String = ""
11+
12+
val i = 10 match
13+
case Foo(x) => x
14+
case Bar(x) => x
15+
case Baz(x) => x

0 commit comments

Comments
 (0)