Skip to content

Commit

Permalink
Backport "Inline transparent implicit parameters when typing Unapply …
Browse files Browse the repository at this point in the history
…trees" to LTS (#21048)

Backports #19646 to the LTS branch.

PR submitted by the release tooling.
[skip ci]
  • Loading branch information
WojciechMazur authored Jul 5, 2024
2 parents 7e78711 + 2740927 commit 827af90
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
12 changes: 12 additions & 0 deletions compiler/src/dotty/tools/dotc/inlines/Inlines.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package inlines
import ast.*, core.*
import Flags.*, Symbols.*, Types.*, Decorators.*, Constants.*, Contexts.*
import StdNames.{tpnme, nme}
import NameOps.*
import typer.*
import NameKinds.BodyRetainerName
import SymDenotations.SymDenotation
Expand Down Expand Up @@ -54,6 +55,16 @@ object Inlines:
def needsInlining(tree: Tree)(using Context): Boolean = tree match {
case Block(_, expr) => needsInlining(expr)
case _ =>
def isUnapplyExpressionWithDummy: Boolean =
// The first step of typing an `unapply` consists in typing the call
// with a dummy argument (see Applications.typedUnApply). We delay the
// inlining of this call.
def rec(tree: Tree): Boolean = tree match
case Apply(_, ProtoTypes.dummyTreeOfType(_) :: Nil) => true
case Apply(fn, _) => rec(fn)
case _ => false
tree.symbol.name.isUnapplyName && rec(tree)

isInlineable(tree.symbol)
&& !tree.tpe.widenTermRefExpr.isInstanceOf[MethodOrPoly]
&& StagingLevel.level == 0
Expand All @@ -64,6 +75,7 @@ object Inlines:
&& !ctx.typer.hasInliningErrors
&& !ctx.base.stopInlining
&& !ctx.mode.is(Mode.NoInline)
&& !isUnapplyExpressionWithDummy
}

private def needsTransparentInlining(tree: Tree)(using Context): Boolean =
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1476,7 +1476,7 @@ trait Applications extends Compatibility {

val dummyArg = dummyTreeOfType(ownType)
val (newUnapplyFn, unapplyApp) =
val unapplyAppCall = withMode(Mode.NoInline):
val unapplyAppCall =
typedExpr(untpd.TypedSplice(Apply(unapplyFn, dummyArg :: Nil)))
inlinedUnapplyFnAndApp(dummyArg, unapplyAppCall)

Expand Down
40 changes: 40 additions & 0 deletions tests/pos/i19623.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import scala.compiletime.*
import scala.language.dynamics

abstract class % extends Selectable

trait Select { type Out <: % }
trait Selector extends Dynamic {
def selectDynamic[S <: Singleton & String](label: S): Any = ???

def unapply[R: RecordLike](record: R)(using
t: Select,
r: RecordLike[t.Out]
): r.ElemTypes = ???
}

trait RecordLike[R] {
type ElemTypes <: Tuple
}


@main def Test = {
val r: %{ val name: String; } = ???

// originally derived in macro, use dummy instance instead
transparent inline given outputRecordLike[R <: %]: RecordLike[R] = null.asInstanceOf[
RecordLike[R] {
type ElemTypes = String *: EmptyTuple
}
]

type FieldSelector = Select { type Out = % { val name: String } }
given fieldSelector: FieldSelector = ???
val selector: Selector = ???

val works = selector.unapply(r)
val works2 = selector.unapply(r)(using summon, fieldSelector, summon)
r match {
case selector(value) => value // compilation error
}
}

0 comments on commit 827af90

Please sign in to comment.