Skip to content

Remove inline from unapply in Tuple cons #8125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -929,10 +929,7 @@ object SymDenotations {
def isSkolem: Boolean = name == nme.SKOLEM

def isInlineMethod(implicit ctx: Context): Boolean =
isAllOf(InlineMethod, butNot = Accessor) &&
!name.isUnapplyName // unapply methods do not count as inline methods
// we need an inline flag on them only do that
// reduceProjection gets access to their rhs
isAllOf(InlineMethod, butNot = Accessor)

/** Is this a Scala 2 macro */
final def isScala2Macro(implicit ctx: Context): Boolean = is(Macro) && symbol.owner.is(Scala2x)
Expand Down
10 changes: 2 additions & 8 deletions compiler/src/dotty/tools/dotc/typer/Checking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1016,14 +1016,8 @@ trait Checking {

/** Check that we are in an inline context (inside an inline method or in inline code) */
def checkInInlineContext(what: String, posd: Positioned)(implicit ctx: Context): Unit =
if (!ctx.inInlineMethod && !ctx.isInlineContext) {
val inInlineUnapply = ctx.owner.ownersIterator.exists(owner =>
owner.name.isUnapplyName && owner.is(Inline) && owner.is(Method))
val msg =
if (inInlineUnapply) "cannot be used in an inline unapply"
else "can only be used in an inline method"
ctx.error(em"$what $msg", posd.sourcePos)
}
if !ctx.inInlineMethod && !ctx.isInlineContext then
ctx.error(em"$what can only be used in an inline method", posd.sourcePos)

/** 1. Check that all case classes that extend `scala.Enum` are `enum` cases
* 2. Check that case class `enum` cases do not extend java.lang.Enum.
Expand Down
6 changes: 0 additions & 6 deletions compiler/src/dotty/tools/dotc/typer/Inliner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -992,12 +992,6 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
yield constToLiteral(reduceProjection(ref(scrut).select(accessor).ensureApplied))
caseAccessors.length == pats.length && reduceSubPatterns(pats, selectors)
}
else if (unapp.symbol.isInlineMethod) { // TODO: Adapt to typed setting
val app = untpd.Apply(untpd.TypedSplice(unapp), untpd.ref(scrut))
val app1 = typer.typedExpr(app)
val args = tupleArgs(app1)
args.nonEmpty && reduceSubPatterns(pats, args)
}
else false
case _ =>
false
Expand Down
9 changes: 4 additions & 5 deletions compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,10 @@ object PrepareInlineable {
if (inlined.owner.isClass && inlined.owner.seesOpaques)
ctx.error(em"Implementation restriction: No inline methods allowed where opaque type aliases are in scope", inlined.sourcePos)
if (ctx.outer.inInlineMethod)
ctx.error(ex"implementation restriction: nested inline methods are not supported", inlined.sourcePos)
if (inlined.name.isUnapplyName && tupleArgs(body).isEmpty)
ctx.warning(
em"inline unapply method can be rewritten only if its right hand side is a tuple (e1, ..., eN)",
body.sourcePos)
ctx.error(ex"Implementation restriction: nested inline methods are not supported", inlined.sourcePos)
if (inlined.name.isUnapplyName)
ctx.error(em"Implementation restriction: inline ${inlined.name} methods are not supported", inlined.sourcePos)

if (inlined.is(Macro) && !ctx.isAfterTyper) {

def checkMacro(tree: Tree): Unit = tree match {
Expand Down
2 changes: 1 addition & 1 deletion library/src/scala/Tuple.scala
Original file line number Diff line number Diff line change
Expand Up @@ -213,5 +213,5 @@ sealed trait NonEmptyTuple extends Tuple {
sealed abstract class *:[+H, +T <: Tuple] extends NonEmptyTuple

object *: {
inline def unapply[H, T <: Tuple](x: H *: T) = (x.head, x.tail)
def unapply[H, T <: Tuple](x: H *: T): (H, T) = (x.head, x.tail)
}
5 changes: 5 additions & 0 deletions tests/neg/inine-unnapply.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

object Foo {
inline def unapply(x: Any): Boolean = ??? // error: Implementation restriction: inline unapply methods are not supported
inline def unapplySeq(x: Any): Seq[Any] = ??? // error: Implementation restriction: inline unapplySeq methods are not supported
}
6 changes: 3 additions & 3 deletions tests/neg/inline-unapply.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ object Test {

class C(val x: Int, val y: Int)

inline def unapply(c: C): Option[(Int, Int)] = Some((c.x, c.y)) // ok
inline def unapply(c: C): Some[(Int, Int)] = Some((c.x, c.y)) // error: Implementation restriction: inline unapply methods are not supported

}
object Test2 {

class C(x: Int, y: Int)

inline def unapply(c: C): Option[(Int, Int)] = inline c match { // error: inline match cannot be used in an inline unapply
case x: C => (1, 1)
inline def unapply(c: C): Option[(Int, Int)] = inline c match { // error: Implementation restriction: inline unapply methods are not supported
case x: C => Some((1, 1))
}
}
4 changes: 2 additions & 2 deletions tests/pos/inline-i1773.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
object Test {
implicit class Foo(sc: StringContext) {
object q {
inline def unapply(arg: Any): Option[(Any, Any)] =
def unapply(arg: Any): Option[(Any, Any)] =
Some((sc.parts(0), sc.parts(1)))
}
}

def main(args: Array[String]): Unit = {
val q"class $name extends $parent" = new Object // now ok, was an error that "method unapply is used"
val q"class $name extends $parent" = new Object
println(name)
println(parent)
}
Expand Down