Skip to content

Commit 5ff35a9

Browse files
committed
Inline transparent implicit parameters when typing Unapply trees
We needed to delay the inlining of the transparent inline when typing the unapply function application. We used the NoInline mode, but this also stopped the inlining of the arguments of the unapply. To fix this we introduce a new mode, NoInlineUnapply, which is used to delay only the inlining of the unapply method and not the implicit arguments. Fixes #19623
1 parent 551eae4 commit 5ff35a9

File tree

4 files changed

+46
-1
lines changed

4 files changed

+46
-1
lines changed

compiler/src/dotty/tools/dotc/core/Mode.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ object Mode {
122122

123123
val PatternOrTypeBits: Mode = Pattern | Type
124124

125+
/** Skip inlining of unapply methods. */
126+
val NoInlineUnapply: Mode = newMode(18, "NoInlineUnapply")
127+
125128
/** We are elaborating the fully qualified name of a package clause.
126129
* In this case, identifiers should never be imported.
127130
*/

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

Lines changed: 2 additions & 0 deletions
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
@@ -64,6 +65,7 @@ object Inlines:
6465
&& !ctx.typer.hasInliningErrors
6566
&& !ctx.base.stopInlining
6667
&& !ctx.mode.is(Mode.NoInline)
68+
&& !(ctx.mode.is(Mode.NoInlineUnapply) && tree.symbol.name.isUnapplyName)
6769
}
6870

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1492,7 +1492,7 @@ trait Applications extends Compatibility {
14921492

14931493
val dummyArg = dummyTreeOfType(ownType)
14941494
val (newUnapplyFn, unapplyApp) =
1495-
val unapplyAppCall = withMode(Mode.NoInline):
1495+
val unapplyAppCall = withMode(Mode.NoInlineUnapply):
14961496
typedExpr(untpd.TypedSplice(Apply(unapplyFn, dummyArg :: Nil)))
14971497
inlinedUnapplyFnAndApp(dummyArg, unapplyAppCall)
14981498

tests/pos/i19623.scala

Lines changed: 40 additions & 0 deletions
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)