From 6d7dd2c16ab49a23ec3e66bc22e7f1ff958ff5b0 Mon Sep 17 00:00:00 2001 From: Allan Renucci Date: Mon, 2 Jul 2018 20:07:48 +0200 Subject: [PATCH] Introduce `@forceInline` annotation An annotation on methods that is equivalent to Dotty `inline` modifier. The annotation should be used instead of the `inline` modifier in code that needs to cross compile between Scala 2 and Dotty. --- compiler/src/dotty/tools/dotc/ast/tpd.scala | 2 +- .../dotty/tools/dotc/core/Definitions.scala | 4 ++-- .../src/dotty/tools/dotc/core/Symbols.scala | 2 +- compiler/src/dotty/tools/dotc/core/Types.scala | 2 +- .../tools/dotc/parsing/xml/MarkupParsers.scala | 2 +- .../dotc/printing/SyntaxHighlighting.scala | 4 ++-- .../dotc/reporting/diagnostic/messages.scala | 2 +- .../src/dotty/tools/dotc/reporting/trace.scala | 14 +++++++------- .../src/dotty/tools/dotc/typer/Inliner.scala | 6 +++--- .../src/dotty/tools/dotc/typer/Namer.scala | 2 +- compiler/src/dotty/tools/dotc/util/Chars.scala | 2 +- compiler/src/dotty/tools/dotc/util/Stats.scala | 6 +++--- .../backend/jvm/InlineBytecodeTests.scala | 18 +++++++++++++----- .../dotc/reporting/ErrorMessagesTests.scala | 2 +- docs/docs/reference/inline.md | 6 ++++++ library/src/dotty/DottyPredef.scala | 8 +++++--- library/src/dotty/runtime/LazyVals.scala | 17 +++++++++-------- library/src/scala/forceInline.scala | 16 ++++++++++++++++ .../src/scala/tasty/util/ShowSourceCode.scala | 2 +- .../inline/changes/B1.scala | 2 +- .../inline/changes/B2.scala | 2 +- .../inline/changes/B3.scala | 2 +- .../inline/project/DottyInjectedPlugin.scala | 3 +-- tests/neg/power.scala | 3 +-- tests/pickling/i2166.scala | 2 +- tests/pos/SI-7060.scala | 2 +- tests/pos/i1891.scala | 2 +- tests/pos/i3636.scala | 4 ++-- tests/pos/inline-access-levels/A_1.scala | 2 +- tests/pos/inline-apply.scala | 2 +- tests/pos/inliner2.scala | 2 +- tests/pos/pos_valueclasses/t5853.scala | 4 ++-- tests/pos/rbtree.scala | 4 ++-- tests/pos/sealed-final.scala | 2 +- tests/pos/simpleInline.scala | 3 +-- tests/pos/t6157.scala | 3 +-- tests/pos/t6562.scala | 6 ++---- tests/run/dead-code-elimination.scala | 2 +- tests/run/genericValueClass.scala | 4 ++-- tests/run/inlineArrowAssoc.scala | 2 +- 40 files changed, 101 insertions(+), 74 deletions(-) create mode 100644 library/src/scala/forceInline.scala diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index a9feeae2da99..b9a6edcc6bc3 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -1052,7 +1052,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { def enclosingInlineds(implicit ctx: Context): List[Tree] = ctx.property(InlinedCalls).getOrElse(Nil) - /** The source file where the symbol of the `@inline` method referred to by `call` + /** The source file where the symbol of the `inline` method referred to by `call` * is defined */ def sourceFile(call: Tree)(implicit ctx: Context) = { diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 77cca3dffe85..3e4d470babdc 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -707,8 +707,8 @@ class Definitions { def ImplicitAmbiguousAnnot(implicit ctx: Context) = ImplicitAmbiguousAnnotType.symbol.asClass lazy val ImplicitNotFoundAnnotType = ctx.requiredClassRef("scala.annotation.implicitNotFound") def ImplicitNotFoundAnnot(implicit ctx: Context) = ImplicitNotFoundAnnotType.symbol.asClass - lazy val InlineAnnotType = ctx.requiredClassRef("scala.inline") - def InlineAnnot(implicit ctx: Context) = InlineAnnotType.symbol.asClass + lazy val ForceInlineAnnotType = ctx.requiredClassRef("scala.forceInline") + def ForceInlineAnnot(implicit ctx: Context) = ForceInlineAnnotType.symbol.asClass lazy val InlineParamAnnotType = ctx.requiredClassRef("scala.annotation.internal.InlineParam") def InlineParamAnnot(implicit ctx: Context) = InlineParamAnnotType.symbol.asClass lazy val InvariantBetweenAnnotType = ctx.requiredClassRef("scala.annotation.internal.InvariantBetween") diff --git a/compiler/src/dotty/tools/dotc/core/Symbols.scala b/compiler/src/dotty/tools/dotc/core/Symbols.scala index 51ad8507f4aa..40ff5b0dfb19 100644 --- a/compiler/src/dotty/tools/dotc/core/Symbols.scala +++ b/compiler/src/dotty/tools/dotc/core/Symbols.scala @@ -803,6 +803,6 @@ object Symbols { override def toString: String = value.asScala.toString() } - @inline def newMutableSymbolMap[T]: MutableSymbolMap[T] = + @forceInline def newMutableSymbolMap[T]: MutableSymbolMap[T] = new MutableSymbolMap(new java.util.IdentityHashMap[Symbol, T]()) } diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index b90a5bde2c98..2040cc6377d9 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -3935,7 +3935,7 @@ object Types { abstract class VariantTraversal { protected[core] var variance = 1 - @inline protected def atVariance[T](v: Int)(op: => T): T = { + @forceInline protected def atVariance[T](v: Int)(op: => T): T = { val saved = variance variance = v val res = op diff --git a/compiler/src/dotty/tools/dotc/parsing/xml/MarkupParsers.scala b/compiler/src/dotty/tools/dotc/parsing/xml/MarkupParsers.scala index 4792f3e3baa7..88789d6a5bb4 100644 --- a/compiler/src/dotty/tools/dotc/parsing/xml/MarkupParsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/xml/MarkupParsers.scala @@ -316,7 +316,7 @@ object MarkupParsers { } /** Some try/catch/finally logic used by xLiteral and xLiteralPattern. */ - @inline private def xLiteralCommon(f: () => Tree, ifTruncated: String => Unit): Tree = { + @forceInline private def xLiteralCommon(f: () => Tree, ifTruncated: String => Unit): Tree = { var output: Tree = null.asInstanceOf[Tree] try output = f() catch { diff --git a/compiler/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala b/compiler/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala index 264a2d5d0500..6c6348e80a03 100644 --- a/compiler/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala +++ b/compiler/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala @@ -51,12 +51,12 @@ object SyntaxHighlighting { val newBuf = new StringBuilder var lastValDefToken = "" - @inline def keywordStart = + @forceInline def keywordStart = prev == 0 || prev == ' ' || prev == '{' || prev == '(' || prev == '\n' || prev == '[' || prev == ',' || prev == ':' || prev == '|' || prev == '&' - @inline def numberStart(c: Char) = + @forceInline def numberStart(c: Char) = c.isDigit && (!prev.isLetter || prev == '.' || prev == ' ' || prev == '(' || prev == '\u0000') def takeChar(): Char = takeChars(1).head diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 79f5c33d8779..2df2e49e85e2 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1748,7 +1748,7 @@ object messages { val kind = "Syntax" val msg = hl"no explicit ${"return"} allowed from inline $owner" val explanation = - hl"""Methods marked with ${"@inline"} may not use ${"return"} statements. + hl"""Methods marked with ${"inline"} modifier may not use ${"return"} statements. |Instead, you should rely on the last expression's value being |returned from a method. |""" diff --git a/compiler/src/dotty/tools/dotc/reporting/trace.scala b/compiler/src/dotty/tools/dotc/reporting/trace.scala index 20617bb2648d..eda7ebe16f97 100644 --- a/compiler/src/dotty/tools/dotc/reporting/trace.scala +++ b/compiler/src/dotty/tools/dotc/reporting/trace.scala @@ -9,11 +9,11 @@ import core.Mode object trace { - @inline + @forceInline def onDebug[TD](question: => String)(op: => TD)(implicit ctx: Context): TD = conditionally(ctx.settings.YdebugTrace.value, question, false)(op) - @inline + @forceInline def conditionally[TC](cond: Boolean, question: => String, show: Boolean)(op: => TC)(implicit ctx: Context): TC = if (Config.tracingEnabled) { def op1 = op @@ -21,7 +21,7 @@ object trace { else op1 } else op - @inline + @forceInline def apply[T](question: => String, printer: Printers.Printer, showOp: Any => String)(op: => T)(implicit ctx: Context): T = if (Config.tracingEnabled) { def op1 = op @@ -30,7 +30,7 @@ object trace { } else op - @inline + @forceInline def apply[T](question: => String, printer: Printers.Printer, show: Boolean)(op: => T)(implicit ctx: Context): T = if (Config.tracingEnabled) { def op1 = op @@ -39,15 +39,15 @@ object trace { } else op - @inline + @forceInline def apply[T](question: => String, printer: Printers.Printer)(op: => T)(implicit ctx: Context): T = apply[T](question, printer, false)(op) - @inline + @forceInline def apply[T](question: => String, show: Boolean)(op: => T)(implicit ctx: Context): T = apply[T](question, Printers.default, show)(op) - @inline + @forceInline def apply[T](question: => String)(op: => T)(implicit ctx: Context): T = apply[T](question, Printers.default, false)(op) diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index cd55764631a6..deabea22d9de 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -229,7 +229,7 @@ object Inliner { } /** `sym` has an inline method with a known body to inline (note: definitions coming - * from Scala2x class files might be `@inline`, but still lack that body. + * from Scala2x class files might be `@forceInline`, but still lack that body. */ def hasBodyToInline(sym: SymDenotation)(implicit ctx: Context): Boolean = sym.isInlinedMethod && sym.hasAnnotation(defn.BodyAnnot) // TODO: Open this up for transparent methods as well @@ -240,7 +240,7 @@ object Inliner { def bodyToInline(sym: SymDenotation)(implicit ctx: Context): Tree = sym.unforcedAnnotation(defn.BodyAnnot).get.tree - /** Try to inline a call to a `@inline` method. Fail with error if the maximal + /** Try to inline a call to a `inline` method. Fail with error if the maximal * inline depth is exceeded. * * @param tree The call to inline @@ -281,7 +281,7 @@ object Inliner { /** Produces an inlined version of `call` via its `inlined` method. * - * @param call the original call to a `@inline` method + * @param call the original call to an `inline` method * @param rhsToInline the body of the inline method that replaces the call. */ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 342061d48471..1adf4ad33bdd 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -751,7 +751,7 @@ class Namer { typer: Typer => if (sym.unforcedAnnotation(cls).isEmpty) { val ann = Annotation.deferred(cls, implicit ctx => typedAheadAnnotation(annotTree)) sym.addAnnotation(ann) - if (cls == defn.InlineAnnot && sym.is(Method, butNot = Accessor)) + if (cls == defn.ForceInlineAnnot && sym.is(Method, butNot = Accessor)) sym.setFlag(Inline) } } diff --git a/compiler/src/dotty/tools/dotc/util/Chars.scala b/compiler/src/dotty/tools/dotc/util/Chars.scala index 29a88aeb13ea..14b6fd0dbf89 100644 --- a/compiler/src/dotty/tools/dotc/util/Chars.scala +++ b/compiler/src/dotty/tools/dotc/util/Chars.scala @@ -38,7 +38,7 @@ object Chars { /** Convert a character to a backslash-u escape */ def char2uescape(c: Char): String = { - @inline def hexChar(ch: Int): Char = + @forceInline def hexChar(ch: Int): Char = (( if (ch < 10) '0' else 'A' - 10 ) + ch).toChar char2uescapeArray(2) = hexChar((c >> 12) ) diff --git a/compiler/src/dotty/tools/dotc/util/Stats.scala b/compiler/src/dotty/tools/dotc/util/Stats.scala index 742ba30723c6..38f0fa0db99d 100644 --- a/compiler/src/dotty/tools/dotc/util/Stats.scala +++ b/compiler/src/dotty/tools/dotc/util/Stats.scala @@ -20,7 +20,7 @@ import collection.mutable override def default(key: String): Int = 0 } - @inline + @forceInline def record(fn: => String, n: => Int = 1) = if (enabled) doRecord(fn, n) @@ -30,7 +30,7 @@ import collection.mutable hits(name) += n } - @inline + @forceInline def track[T](fn: String)(op: => T) = if (enabled) doTrack(fn)(op) else op @@ -42,7 +42,7 @@ import collection.mutable finally stack = stack.tail } else op - @inline + @forceInline def trackTime[T](fn: String)(op: => T) = if (enabled) doTrackTime(fn)(op) else op diff --git a/compiler/test/dotty/tools/backend/jvm/InlineBytecodeTests.scala b/compiler/test/dotty/tools/backend/jvm/InlineBytecodeTests.scala index 033783303df0..464b427c8993 100644 --- a/compiler/test/dotty/tools/backend/jvm/InlineBytecodeTests.scala +++ b/compiler/test/dotty/tools/backend/jvm/InlineBytecodeTests.scala @@ -9,24 +9,32 @@ class InlineBytecodeTests extends DottyBytecodeTest { val source = """ |class Foo { | inline def foo: Int = 1 + | @forceInline def bar: Int = 1 | | def meth1: Unit = foo - | def meth2: Unit = 1 + | def meth2: Unit = bar + | def meth3: Unit = 1 |} """.stripMargin checkBCode(source) { dir => val clsIn = dir.lookupName("Foo.class", directory = false).input val clsNode = loadClassNode(clsIn) - val meth1 = getMethod(clsNode, "meth1") - val meth2 = getMethod(clsNode, "meth2") + val meth1 = getMethod(clsNode, "meth1") + val meth2 = getMethod(clsNode, "meth2") + val meth3 = getMethod(clsNode, "meth3") val instructions1 = instructionsFromMethod(meth1) val instructions2 = instructionsFromMethod(meth2) + val instructions3 = instructionsFromMethod(meth3) - assert(instructions1 == instructions2, + assert(instructions1 == instructions3, "`foo` was not properly inlined in `meth1`\n" + - diffInstructions(instructions1, instructions2)) + diffInstructions(instructions1, instructions3)) + + assert(instructions2 == instructions3, + "`bar` was not properly inlined in `meth2`\n" + + diffInstructions(instructions2, instructions3)) } } } diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index d8327bc3a56b..927e1f42a009 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -935,7 +935,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { @Test def noReturnInInline = checkMessagesAfter(FrontEnd.name) { """class BadFunction { - | @inline def usesReturn: Int = { return 42 } + | inline def usesReturn: Int = { return 42 } |} """.stripMargin }.expect { (ictx, messages) => diff --git a/docs/docs/reference/inline.md b/docs/docs/reference/inline.md index c43b0e8a59e4..372bbeda73c1 100644 --- a/docs/docs/reference/inline.md +++ b/docs/docs/reference/inline.md @@ -125,6 +125,12 @@ it in backticks, i.e. @`inline` def ... +The Dotty compiler ignores `@inline` annotated definitions. To cross +compile between both Dotty and Scalac, we introduce a new `@forceInline` +annotation which is equivalent to the new `inline` modifier. Note that +Scala 2 ignores the `@forceInLine` annotation, and one must use both +annotations to inline across the two compilers (i.e. `@forceInline @inline`). + ### The definition of constant expression Right-hand sides of inline values and of arguments for inline parameters diff --git a/library/src/dotty/DottyPredef.scala b/library/src/dotty/DottyPredef.scala index 3666b2ac525b..632604e4691d 100644 --- a/library/src/dotty/DottyPredef.scala +++ b/library/src/dotty/DottyPredef.scala @@ -1,5 +1,7 @@ package dotty +import scala.forceInline + object DottyPredef { /** A class for implicit values that can serve as implicit conversions @@ -22,12 +24,12 @@ object DottyPredef { */ abstract class ImplicitConverter[-T, +U] extends Function1[T, U] - @inline final def assert(assertion: Boolean, message: => Any): Unit = { + @forceInline final def assert(assertion: Boolean, message: => Any): Unit = { if (!assertion) assertFail(message) } - @inline final def assert(assertion: Boolean): Unit = { + @forceInline final def assert(assertion: Boolean): Unit = { if (!assertion) assertFail() } @@ -35,5 +37,5 @@ object DottyPredef { final def assertFail(): Unit = throw new java.lang.AssertionError("assertion failed") final def assertFail(message: => Any): Unit = throw new java.lang.AssertionError("assertion failed: " + message) - @inline final def implicitly[T](implicit ev: T): T = ev + @forceInline final def implicitly[T](implicit ev: T): T = ev } diff --git a/library/src/dotty/runtime/LazyVals.scala b/library/src/dotty/runtime/LazyVals.scala index 2c06a5dd8f05..04114a156c06 100644 --- a/library/src/dotty/runtime/LazyVals.scala +++ b/library/src/dotty/runtime/LazyVals.scala @@ -1,6 +1,7 @@ package dotty.runtime import scala.annotation.tailrec +import scala.forceInline /** * Helper methods used in thread-safe lazy vals. @@ -24,20 +25,20 @@ object LazyVals { final val LAZY_VAL_MASK = 3L final val debug = false - @inline def STATE(cur: Long, ord: Int) = { + @forceInline def STATE(cur: Long, ord: Int) = { val r = (cur >> (ord * BITS_PER_LAZY_VAL)) & LAZY_VAL_MASK if (debug) println(s"STATE($cur, $ord) = $r") r } - @inline def CAS(t: Object, offset: Long, e: Long, v: Int, ord: Int) = { + @forceInline def CAS(t: Object, offset: Long, e: Long, v: Int, ord: Int) = { if (debug) println(s"CAS($t, $offset, $e, $v, $ord)") val mask = ~(LAZY_VAL_MASK << ord * BITS_PER_LAZY_VAL) val n = (e & mask) | (v.toLong << (ord * BITS_PER_LAZY_VAL)) compareAndSet(t, offset, e, n) } - @inline def setFlag(t: Object, offset: Long, v: Int, ord: Int) = { + @forceInline def setFlag(t: Object, offset: Long, v: Int, ord: Int) = { if (debug) println(s"setFlag($t, $offset, $v, $ord)") var retry = true @@ -56,7 +57,7 @@ object LazyVals { } } } - @inline def wait4Notification(t: Object, offset: Long, cur: Long, ord: Int) = { + @forceInline def wait4Notification(t: Object, offset: Long, cur: Long, ord: Int) = { if (debug) println(s"wait4Notification($t, $offset, $cur, $ord)") var retry = true @@ -74,8 +75,8 @@ object LazyVals { } } - @inline def compareAndSet(t: Object, off: Long, e: Long, v: Long) = unsafe.compareAndSwapLong(t, off, e, v) - @inline def get(t: Object, off: Long) = { + @forceInline def compareAndSet(t: Object, off: Long, e: Long, v: Long) = unsafe.compareAndSwapLong(t, off, e, v) + @forceInline def get(t: Object, off: Long) = { if (debug) println(s"get($t, $off)") unsafe.getLongVolatile(t, off) @@ -87,7 +88,7 @@ object LazyVals { x => new Object() }.toArray - @inline def getMonitor(obj: Object, fieldId: Int = 0) = { + @forceInline def getMonitor(obj: Object, fieldId: Int = 0) = { var id = ( /*java.lang.System.identityHashCode(obj) + */ // should be here, but #548 fieldId) % base @@ -96,7 +97,7 @@ object LazyVals { monitors(id) } - @inline def getOffset(clz: Class[_], name: String) = { + @forceInline def getOffset(clz: Class[_], name: String) = { val r = unsafe.objectFieldOffset(clz.getDeclaredField(name)) if (debug) println(s"getOffset($clz, $name) = $r") diff --git a/library/src/scala/forceInline.scala b/library/src/scala/forceInline.scala new file mode 100644 index 000000000000..08eb0e59462a --- /dev/null +++ b/library/src/scala/forceInline.scala @@ -0,0 +1,16 @@ +package scala + +/** An annotation on methods that is equivalent to Dotty `inline` modifier. + * + * The annotation should be used instead of the `inline` modifier in code + * that needs to cross compile between Scala 2 and Dotty. + * + * Note that Scala 2 ignores the `@forceInLine` annotation, and one must use + * both the `@inline` and `@forceInline` annotation to inline across the + * two compilers. E.g. + * + * ```scala + * @inline @forceInline def foo = ... + * ``` + */ +class forceInline extends scala.annotation.StaticAnnotation diff --git a/library/src/scala/tasty/util/ShowSourceCode.scala b/library/src/scala/tasty/util/ShowSourceCode.scala index dd492708b87c..c3288ae3e7f0 100644 --- a/library/src/scala/tasty/util/ShowSourceCode.scala +++ b/library/src/scala/tasty/util/ShowSourceCode.scala @@ -949,7 +949,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case Annotation(annot, _) => annot.tpe match { case Type.TypeRef(_, Type.SymRef(PackageDef("internal", _), Type.ThisType(Type.SymRef(PackageDef("annotation", _), NoPrefix())))) => false - case Type.TypeRef("inline", Types.ScalaPackage()) => false + case Type.TypeRef("forceInline", Types.ScalaPackage()) => false case _ => true } case x => throw new MatchError(x.show) diff --git a/sbt-dotty/sbt-test/source-dependencies/inline/changes/B1.scala b/sbt-dotty/sbt-test/source-dependencies/inline/changes/B1.scala index 5685152b3819..fc714b93b0a9 100644 --- a/sbt-dotty/sbt-test/source-dependencies/inline/changes/B1.scala +++ b/sbt-dotty/sbt-test/source-dependencies/inline/changes/B1.scala @@ -1,4 +1,4 @@ object B { - @inline def getInline: Int = + inline def getInline: Int = A.get } diff --git a/sbt-dotty/sbt-test/source-dependencies/inline/changes/B2.scala b/sbt-dotty/sbt-test/source-dependencies/inline/changes/B2.scala index 1de104357e41..9a3abb0d9792 100644 --- a/sbt-dotty/sbt-test/source-dependencies/inline/changes/B2.scala +++ b/sbt-dotty/sbt-test/source-dependencies/inline/changes/B2.scala @@ -1,4 +1,4 @@ object B { - @inline def getInline: Double = + inline def getInline: Double = A.get } diff --git a/sbt-dotty/sbt-test/source-dependencies/inline/changes/B3.scala b/sbt-dotty/sbt-test/source-dependencies/inline/changes/B3.scala index 991bd17b893a..2fffbde1bbf9 100644 --- a/sbt-dotty/sbt-test/source-dependencies/inline/changes/B3.scala +++ b/sbt-dotty/sbt-test/source-dependencies/inline/changes/B3.scala @@ -1,4 +1,4 @@ object B { - @inline def getInline: Int = + inline def getInline: Int = sys.error("This is an expected failure when running C") } diff --git a/sbt-dotty/sbt-test/source-dependencies/inline/project/DottyInjectedPlugin.scala b/sbt-dotty/sbt-test/source-dependencies/inline/project/DottyInjectedPlugin.scala index ce3d46d79921..fb946c4b8c61 100644 --- a/sbt-dotty/sbt-test/source-dependencies/inline/project/DottyInjectedPlugin.scala +++ b/sbt-dotty/sbt-test/source-dependencies/inline/project/DottyInjectedPlugin.scala @@ -6,7 +6,6 @@ object DottyInjectedPlugin extends AutoPlugin { override def trigger = allRequirements override val projectSettings = Seq( - scalaVersion := sys.props("plugin.scalaVersion"), - scalacOptions += "-language:Scala2" + scalaVersion := sys.props("plugin.scalaVersion") ) } diff --git a/tests/neg/power.scala b/tests/neg/power.scala index 6230b4e51a21..d5098fc215ed 100644 --- a/tests/neg/power.scala +++ b/tests/neg/power.scala @@ -1,7 +1,6 @@ object Test { - @inline - def power(x: Double, n: Int): Double = + inline def power(x: Double, n: Int): Double = if (n == 0) 1.0 else if (n == 1) x else { diff --git a/tests/pickling/i2166.scala b/tests/pickling/i2166.scala index 7199b7a3613c..f796031d009d 100644 --- a/tests/pickling/i2166.scala +++ b/tests/pickling/i2166.scala @@ -1,5 +1,5 @@ object Test { - @inline def f = "" match { case _ => false } + inline def f = "" match { case _ => false } def main(args: Array[String]): Unit = f } \ No newline at end of file diff --git a/tests/pos/SI-7060.scala b/tests/pos/SI-7060.scala index c87620e0208a..d6f172d45283 100644 --- a/tests/pos/SI-7060.scala +++ b/tests/pos/SI-7060.scala @@ -1,6 +1,6 @@ object Test { - @inline final def mbarray_apply_minibox(array: Any, tag: Byte): Long = + inline final def mbarray_apply_minibox(array: Any, tag: Byte): Long = if (tag == 0) { array.asInstanceOf[Array[Long]](0) } else diff --git a/tests/pos/i1891.scala b/tests/pos/i1891.scala index b178c256b3c4..794b27a35e8e 100644 --- a/tests/pos/i1891.scala +++ b/tests/pos/i1891.scala @@ -4,7 +4,7 @@ object Test { type T2[A, B] = CC2[A, B] class ArrowAssoc[A](val self: A) { - @inline def f[B](y: B): CC2[A, B] = new CC2(self, y) + inline def f[B](y: B): CC2[A, B] = new CC2(self, y) } def foo = (new ArrowAssoc(1)).f(2) diff --git a/tests/pos/i3636.scala b/tests/pos/i3636.scala index f250ab94b542..9597bf25ba8b 100644 --- a/tests/pos/i3636.scala +++ b/tests/pos/i3636.scala @@ -1,11 +1,11 @@ trait Iterable[A] { def concat[B >: A](that: Iterable[B]): Iterable[B] = ??? - @`inline` final def ++ [B >: A](that: Iterable[B]): Iterable[B] = concat(that) + inline final def ++ [B >: A](that: Iterable[B]): Iterable[B] = concat(that) } class BitSet extends Iterable[Int] { def concat(that: Iterable[Int]): BitSet = ??? - @`inline` final def ++ (that: Iterable[Int]): BitSet = concat(that) + inline final def ++ (that: Iterable[Int]): BitSet = concat(that) } class Test { diff --git a/tests/pos/inline-access-levels/A_1.scala b/tests/pos/inline-access-levels/A_1.scala index 479fe0fc7163..97f9392b17c1 100644 --- a/tests/pos/inline-access-levels/A_1.scala +++ b/tests/pos/inline-access-levels/A_1.scala @@ -4,7 +4,7 @@ object A { private var x: Int = 0 - @inline def actOnX(f: Int => Int) = { + inline def actOnX(f: Int => Int) = { x = f(x) } } diff --git a/tests/pos/inline-apply.scala b/tests/pos/inline-apply.scala index ab25f2b4bf2e..6cdfe3b3ccb2 100644 --- a/tests/pos/inline-apply.scala +++ b/tests/pos/inline-apply.scala @@ -3,7 +3,7 @@ class Context object Test { def transform()(implicit ctx: Context) = { - @inline def withLocalOwner[T](op: Context => T) = op(ctx) + inline def withLocalOwner[T](op: Context => T) = op(ctx) withLocalOwner { implicit ctx => } diff --git a/tests/pos/inliner2.scala b/tests/pos/inliner2.scala index bc83e04312d2..7b9099310a32 100644 --- a/tests/pos/inliner2.scala +++ b/tests/pos/inliner2.scala @@ -3,7 +3,7 @@ // for inlining due to the bug. class A { private var debug = false - @inline private def ifelse[T](cond: => Boolean, ifPart: => T, elsePart: => T): T = + inline private def ifelse[T](cond: => Boolean, ifPart: => T, elsePart: => T): T = if (cond) ifPart else elsePart final def bob1() = ifelse(debug, 1, 2) diff --git a/tests/pos/pos_valueclasses/t5853.scala b/tests/pos/pos_valueclasses/t5853.scala index 82ac9dd1dd24..b615cde71200 100644 --- a/tests/pos/pos_valueclasses/t5853.scala +++ b/tests/pos/pos_valueclasses/t5853.scala @@ -41,7 +41,7 @@ class Foo2 { object Arrow { implicit final class ArrowAssoc[A](val __leftOfArrow: A) extends AnyVal { - @inline def ->>[B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y) + inline def ->>[B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y) } def foo = 1 ->> 2 @@ -50,7 +50,7 @@ object Arrow { object SpecArrow { implicit final class ArrowAssoc[A](val __leftOfArrow: A) extends AnyVal { - @inline def ->> [@specialized(Int) B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y) + inline def ->> [@specialized(Int) B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y) } def foo = 1 ->> 2 diff --git a/tests/pos/rbtree.scala b/tests/pos/rbtree.scala index 1ca9c57ddcc1..ffa44f743137 100644 --- a/tests/pos/rbtree.scala +++ b/tests/pos/rbtree.scala @@ -457,11 +457,11 @@ object RedBlackTree { } object RedTree { - @inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new RedTree(key, value, left, right) + inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new RedTree(key, value, left, right) def unapply[A, B](t: RedTree[A, B]) = Some((t.key, t.value, t.left, t.right)) } object BlackTree { - @inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new BlackTree(key, value, left, right) + inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new BlackTree(key, value, left, right) def unapply[A, B](t: BlackTree[A, B]) = Some((t.key, t.value, t.left, t.right)) } diff --git a/tests/pos/sealed-final.scala b/tests/pos/sealed-final.scala index bdedb5c1f632..e062888e2668 100644 --- a/tests/pos/sealed-final.scala +++ b/tests/pos/sealed-final.scala @@ -1,5 +1,5 @@ sealed abstract class Foo { - @inline def bar(x: Int) = x + 1 + inline def bar(x: Int) = x + 1 } object Foo { def mkFoo(): Foo = new Baz2 diff --git a/tests/pos/simpleInline.scala b/tests/pos/simpleInline.scala index 9fb0ab8f3bd5..4cfab0209754 100644 --- a/tests/pos/simpleInline.scala +++ b/tests/pos/simpleInline.scala @@ -1,5 +1,4 @@ - class Foo { - @inline def foo: Int = 9 + inline def foo: Int = 9 def bar: Int = foo } diff --git a/tests/pos/t6157.scala b/tests/pos/t6157.scala index 294387cc67d9..89e503c78990 100644 --- a/tests/pos/t6157.scala +++ b/tests/pos/t6157.scala @@ -12,8 +12,7 @@ import java.io.IOException object ErrorHandler { - @inline - def defaultIfIOException[T](default: => T)(closure: => T): T = { + inline def defaultIfIOException[T](default: => T)(closure: => T): T = { try { closure } catch { diff --git a/tests/pos/t6562.scala b/tests/pos/t6562.scala index 600234a297ea..bf8ed8679c1e 100644 --- a/tests/pos/t6562.scala +++ b/tests/pos/t6562.scala @@ -1,13 +1,11 @@ class Test { - @inline - def foo: Unit = { + inline def foo: Unit = { def it = new {} (_: Any) => it } - @inline - private def bar: Unit = { + inline private def bar: Unit = { def it = new {} (_: Any) => it } diff --git a/tests/run/dead-code-elimination.scala b/tests/run/dead-code-elimination.scala index fd3f2a996a20..f5331f47973d 100644 --- a/tests/run/dead-code-elimination.scala +++ b/tests/run/dead-code-elimination.scala @@ -18,7 +18,7 @@ final class A { def f1 = true def f2 = true - @inline def f3 = f1 || f2 + inline def f3 = f1 || f2 class B { def f() = 1 to 10 foreach (_ => f3) } diff --git a/tests/run/genericValueClass.scala b/tests/run/genericValueClass.scala index 5873eace1443..689e0e251e2f 100644 --- a/tests/run/genericValueClass.scala +++ b/tests/run/genericValueClass.scala @@ -3,12 +3,12 @@ import scala.language.implicitConversions object Test extends dotty.runtime.LegacyApp { class ArrowAssocClass[A](val __leftOfArrow: A) extends AnyVal { - @inline def -> [B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y) + inline def -> [B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y) def →[B](y: B): Tuple2[A, B] = ->(y) } { - @inline implicit def ArrowAssoc[A](x: A): ArrowAssocClass[A] = new ArrowAssocClass(x) + inline implicit def ArrowAssoc[A](x: A): ArrowAssocClass[A] = new ArrowAssocClass(x) val x = 1 -> "abc" println(x) } diff --git a/tests/run/inlineArrowAssoc.scala b/tests/run/inlineArrowAssoc.scala index c3625609a14a..0a3b5c6d7e37 100644 --- a/tests/run/inlineArrowAssoc.scala +++ b/tests/run/inlineArrowAssoc.scala @@ -10,7 +10,7 @@ object Test { ) final implicit class ArrowAssoc[A](private val self: A) extends AnyVal { - @inline def -> [B](y: B): Tuple2[A, B] = Tuple2(self, y) + inline def -> [B](y: B): Tuple2[A, B] = Tuple2(self, y) def →[B](y: B): Tuple2[A, B] = ->(y) }