diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 73380bd7bbfd..e0f07e8f7e6c 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -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) diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 4351164fdc3a..74db0593cfc5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -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. diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index c824e9ef403e..ff468264da3b 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -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 diff --git a/compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala b/compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala index 5d28a897ed17..7091f8771408 100644 --- a/compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala +++ b/compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala @@ -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 { diff --git a/library/src/scala/Tuple.scala b/library/src/scala/Tuple.scala index 0785f370c43e..dbb1abccb840 100644 --- a/library/src/scala/Tuple.scala +++ b/library/src/scala/Tuple.scala @@ -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) } diff --git a/tests/neg/inine-unnapply.scala b/tests/neg/inine-unnapply.scala new file mode 100644 index 000000000000..db82997e5648 --- /dev/null +++ b/tests/neg/inine-unnapply.scala @@ -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 +} diff --git a/tests/neg/inline-unapply.scala b/tests/neg/inline-unapply.scala index 98fdf3ad4b12..818bc38f9c82 100644 --- a/tests/neg/inline-unapply.scala +++ b/tests/neg/inline-unapply.scala @@ -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)) } } \ No newline at end of file diff --git a/tests/pos/inline-i1773.scala b/tests/pos/inline-i1773.scala index f66b96f09b50..4791856bb9a7 100644 --- a/tests/pos/inline-i1773.scala +++ b/tests/pos/inline-i1773.scala @@ -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) }