Skip to content

Commit f9d286a

Browse files
committed
Properly refine type of inlined unapply pattern
Fixes #17525
1 parent 18df4ed commit f9d286a

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

compiler/src/dotty/tools/dotc/inlines/Inlines.scala

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ package inlines
44

55
import ast.*, core.*
66
import Flags.*, Symbols.*, Types.*, Decorators.*, Constants.*, Contexts.*
7-
import StdNames.tpnme
7+
import StdNames.{tpnme, nme}
88
import transform.SymUtils._
99
import typer.*
1010
import NameKinds.BodyRetainerName
@@ -193,23 +193,29 @@ object Inlines:
193193

194194
val sym = unapp.symbol
195195

196-
var unapplySym1: Symbol = NoSymbol // created from within AnonClass() and used afterwards
197-
198196
val newUnapply = AnonClass(ctx.owner, List(defn.ObjectType), sym.coord) { cls =>
199197
// `fun` is a partially applied method that contains all type applications of the method.
200198
// The methodic type `fun.tpe.widen` is the type of the function starting from the scrutinee argument
201199
// and its type parameters are instantiated.
202-
val unapplySym = newSymbol(cls, sym.name.toTermName, Synthetic | Method, fun.tpe.widen, coord = sym.coord).entered
203-
val unapply = DefDef(unapplySym.asTerm, argss =>
204-
val body = fun.appliedToArgss(argss).withSpan(unapp.span)
205-
if body.symbol.is(Transparent) then inlineCall(body)(using ctx.withOwner(unapplySym))
206-
else body
207-
)
208-
unapplySym1 = unapplySym
209-
List(unapply)
200+
val unapplyInfo = fun.tpe.widen
201+
val unapplySym = newSymbol(cls, sym.name.toTermName, Synthetic | Method, unapplyInfo, coord = sym.coord).entered
202+
203+
val unapply = DefDef(unapplySym.asTerm, argss => fun.appliedToArgss(argss).withSpan(unapp.span))
204+
205+
if fun.symbol.is(Transparent) then
206+
// Inline the body and refine the type of the unapply method
207+
val inlinedBody = inlineCall(unapply.rhs)(using ctx.withOwner(unapplySym))
208+
val refinedResultType = inlinedBody.tpe.widen
209+
def refinedResult(info: Type): Type = info match
210+
case info: LambdaType => info.newLikeThis(info.paramNames, info.paramInfos, refinedResult(info.resultType))
211+
case _ => refinedResultType
212+
unapplySym.info = refinedResult(unapplyInfo)
213+
List(cpy.DefDef(unapply)(tpt = TypeTree(refinedResultType), rhs = inlinedBody))
214+
else
215+
List(unapply)
210216
}
211217

212-
val newFun = newUnapply.select(unapplySym1).withSpan(unapp.span)
218+
val newFun = newUnapply.select(sym.name).withSpan(unapp.span)
213219
cpy.UnApply(unapp)(newFun, trailingImplicits, patterns)
214220
end inlinedUnapply
215221

tests/pos/i17525.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
object Extract {
2+
transparent inline def unapply(value: String): Option[Tuple] = Some((1, "two"))
3+
}
4+
def fail(): Unit = "" match { case Extract(a, b) => }

0 commit comments

Comments
 (0)