Skip to content

Commit d01b69b

Browse files
committed
Allow inline unapply
Unapply methods can have `inline` flags. This enables reduceProjection to see the methods right hand side. On the other hand, since `unapply` methods are not applied hen used in patterns we do not classify them as inline methods. Consequently they cannot contain inline matches or inline ifs.
1 parent 0581219 commit d01b69b

File tree

3 files changed

+12
-11
lines changed

3 files changed

+12
-11
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,10 @@ object SymDenotations {
793793
def isSkolem: Boolean = name == nme.SKOLEM
794794

795795
def isInlineMethod(implicit ctx: Context): Boolean =
796-
is(InlineMethod, butNot = AccessorOrSynthetic)
796+
is(InlineMethod, butNot = AccessorOrSynthetic) &&
797+
name != nme.unapply // unapply methods do not count as inline methods
798+
// we need an inline flag on them only do that
799+
// reduceProjection gets access to their rhs
797800

798801
/** An erased value or an inline method, excluding @forceInline annotated methods.
799802
* The latter have to be kept around to get to parity with Scala.

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -982,14 +982,6 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
982982
else trySelectUnapply(qual1)(_ => notAnExtractor(sel))
983983
}
984984

985-
/* Can probably be dropped. The idea is that inline unapply methods are available
986-
* for inspection in the Inliner's reduceMatch method, but are never inlined
987-
* when called from normal code.
988-
989-
if (unapplyFn.symbol.isInlineMethod)
990-
checkInInlineContext("implementation restriction: call to inline unapply", tree.pos)
991-
*/
992-
993985
/** Add a `Bind` node for each `bound` symbol in a type application `unapp` */
994986
def addBinders(unapp: Tree, bound: List[Symbol]) = unapp match {
995987
case TypeApply(fn, args) =>

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -891,8 +891,14 @@ trait Checking {
891891

892892
/** Check that we are in an inline context (inside an inline method or in inline code) */
893893
def checkInInlineContext(what: String, pos: Position)(implicit ctx: Context): Unit =
894-
if (!ctx.inInlineMethod && !ctx.isInlineContext)
895-
ctx.error(em"$what can only be used in an inline method", pos)
894+
if (!ctx.inInlineMethod && !ctx.isInlineContext) {
895+
val inInlineUnapply = ctx.owner.ownersIterator.exists(owner =>
896+
owner.name == nme.unapply && owner.is(Inline) && owner.is(Method))
897+
val msg =
898+
if (inInlineUnapply) "cannot be used in an inline unapply"
899+
else "can only be used in an inline method"
900+
ctx.error(em"$what $msg", pos)
901+
}
896902

897903
/** Check that all case classes that extend `scala.Enum` are `enum` cases */
898904
def checkEnum(cdef: untpd.TypeDef, cls: Symbol, parent: Symbol)(implicit ctx: Context): Unit = {

0 commit comments

Comments
 (0)