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

+3
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

+2
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

+1-1
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

+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)