Skip to content

Commit dea9ef3

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

File tree

2 files changed

+21
-12
lines changed

2 files changed

+21
-12
lines changed

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

Lines changed: 17 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,28 @@ 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+
val unapply = DefDef(unapplySym.asTerm, argss => fun.appliedToArgss(argss).withSpan(unapp.span))
203+
204+
if fun.symbol.is(Transparent) then
205+
// Inline the body and refine the type of the unapply method
206+
val inlinedBody = inlineCall(unapply.rhs)(using ctx.withOwner(unapplySym))
207+
val refinedResultType = inlinedBody.tpe.widen
208+
def refinedResult(info: Type): Type = info match
209+
case info: LambdaType => info.newLikeThis(info.paramNames, info.paramInfos, refinedResult(info.resultType))
210+
case _ => refinedResultType
211+
unapplySym.info = refinedResult(unapplyInfo)
212+
List(cpy.DefDef(unapply)(tpt = TypeTree(refinedResultType), rhs = inlinedBody))
213+
else
214+
List(unapply)
210215
}
211216

212-
val newFun = newUnapply.select(unapplySym1).withSpan(unapp.span)
217+
val newFun = newUnapply.select(nme.unapply).withSpan(unapp.span)
213218
cpy.UnApply(unapp)(newFun, trailingImplicits, patterns)
214219
end inlinedUnapply
215220

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)