Skip to content

Commit 827af90

Browse files
Backport "Inline transparent implicit parameters when typing Unapply trees" to LTS (#21048)
Backports #19646 to the LTS branch. PR submitted by the release tooling. [skip ci]
2 parents 7e78711 + 2740927 commit 827af90

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

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

+12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package inlines
55
import ast.*, core.*
66
import Flags.*, Symbols.*, Types.*, Decorators.*, Constants.*, Contexts.*
77
import StdNames.{tpnme, nme}
8+
import NameOps.*
89
import typer.*
910
import NameKinds.BodyRetainerName
1011
import SymDenotations.SymDenotation
@@ -54,6 +55,16 @@ object Inlines:
5455
def needsInlining(tree: Tree)(using Context): Boolean = tree match {
5556
case Block(_, expr) => needsInlining(expr)
5657
case _ =>
58+
def isUnapplyExpressionWithDummy: Boolean =
59+
// The first step of typing an `unapply` consists in typing the call
60+
// with a dummy argument (see Applications.typedUnApply). We delay the
61+
// inlining of this call.
62+
def rec(tree: Tree): Boolean = tree match
63+
case Apply(_, ProtoTypes.dummyTreeOfType(_) :: Nil) => true
64+
case Apply(fn, _) => rec(fn)
65+
case _ => false
66+
tree.symbol.name.isUnapplyName && rec(tree)
67+
5768
isInlineable(tree.symbol)
5869
&& !tree.tpe.widenTermRefExpr.isInstanceOf[MethodOrPoly]
5970
&& StagingLevel.level == 0
@@ -64,6 +75,7 @@ object Inlines:
6475
&& !ctx.typer.hasInliningErrors
6576
&& !ctx.base.stopInlining
6677
&& !ctx.mode.is(Mode.NoInline)
78+
&& !isUnapplyExpressionWithDummy
6779
}
6880

6981
private def needsTransparentInlining(tree: Tree)(using Context): Boolean =

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,7 @@ trait Applications extends Compatibility {
14761476

14771477
val dummyArg = dummyTreeOfType(ownType)
14781478
val (newUnapplyFn, unapplyApp) =
1479-
val unapplyAppCall = withMode(Mode.NoInline):
1479+
val unapplyAppCall =
14801480
typedExpr(untpd.TypedSplice(Apply(unapplyFn, dummyArg :: Nil)))
14811481
inlinedUnapplyFnAndApp(dummyArg, unapplyAppCall)
14821482

tests/pos/i19623.scala

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import scala.compiletime.*
2+
import scala.language.dynamics
3+
4+
abstract class % extends Selectable
5+
6+
trait Select { type Out <: % }
7+
trait Selector extends Dynamic {
8+
def selectDynamic[S <: Singleton & String](label: S): Any = ???
9+
10+
def unapply[R: RecordLike](record: R)(using
11+
t: Select,
12+
r: RecordLike[t.Out]
13+
): r.ElemTypes = ???
14+
}
15+
16+
trait RecordLike[R] {
17+
type ElemTypes <: Tuple
18+
}
19+
20+
21+
@main def Test = {
22+
val r: %{ val name: String; } = ???
23+
24+
// originally derived in macro, use dummy instance instead
25+
transparent inline given outputRecordLike[R <: %]: RecordLike[R] = null.asInstanceOf[
26+
RecordLike[R] {
27+
type ElemTypes = String *: EmptyTuple
28+
}
29+
]
30+
31+
type FieldSelector = Select { type Out = % { val name: String } }
32+
given fieldSelector: FieldSelector = ???
33+
val selector: Selector = ???
34+
35+
val works = selector.unapply(r)
36+
val works2 = selector.unapply(r)(using summon, fieldSelector, summon)
37+
r match {
38+
case selector(value) => value // compilation error
39+
}
40+
}

0 commit comments

Comments
 (0)