aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/config/ScalaSettings.scala1
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala5
-rw-r--r--src/dotty/tools/dotc/core/StdNames.scala1
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala19
-rw-r--r--src/dotty/tools/dotc/parsing/Scanners.scala29
-rw-r--r--src/dotty/tools/dotc/parsing/Tokens.scala6
-rw-r--r--src/dotty/tools/dotc/printing/SyntaxHighlighting.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala15
-rw-r--r--tests/neg/inlineAccess/C_1.scala3
-rw-r--r--tests/pos/rbtree.scala10
-rw-r--r--tests/run/inline/inlines_1.scala12
-rw-r--r--tests/run/inlineLazy.scala6
-rw-r--r--tests/run/inlinePower/power_1.scala3
-rw-r--r--tests/run/inlinePrivates.scala32
-rw-r--r--tests/run/inlinedAssign.scala6
15 files changed, 80 insertions, 70 deletions
diff --git a/src/dotty/tools/dotc/config/ScalaSettings.scala b/src/dotty/tools/dotc/config/ScalaSettings.scala
index 42e761c2e..ff17a9939 100644
--- a/src/dotty/tools/dotc/config/ScalaSettings.scala
+++ b/src/dotty/tools/dotc/config/ScalaSettings.scala
@@ -121,7 +121,6 @@ class ScalaSettings extends Settings.SettingGroup {
val debugOwners = BooleanSetting("-Ydebug-owners", "Print all owners of definitions (requires -Yprint-syms)")
//val doc = BooleanSetting ("-Ydoc", "Generate documentation")
val termConflict = ChoiceSetting("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", List("package", "object", "error"), "error")
- val inline = BooleanSetting("-Yinline", "Perform inlining when possible.")
val inlineHandlers = BooleanSetting("-Yinline-handlers", "Perform exception handler inlining when possible.")
val YinlinerWarnings = BooleanSetting("-Yinline-warnings", "Emit inlining warnings. (Normally surpressed due to high volume)")
val Ylinearizer = ChoiceSetting("-Ylinearizer", "which", "Linearizer to use", List("normal", "dfs", "rpo", "dump"), "rpo")
diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala
index 0cdae6b98..bc5953a2c 100644
--- a/src/dotty/tools/dotc/core/Flags.scala
+++ b/src/dotty/tools/dotc/core/Flags.scala
@@ -450,7 +450,7 @@ object Flags {
AccessFlags | Module | Package | Deferred | Final | MethodOrHKCommon | Param | ParamAccessor | Scala2ExistentialCommon |
Mutable.toCommonFlags | InSuperCall | Touched | JavaStatic | CovariantOrOuter | ContravariantOrLabel | ExpandedName | AccessorOrSealed |
CaseAccessorOrBaseTypeArg | Fresh | Frozen | Erroneous | ImplicitCommon | Permanent | Synthetic |
- LazyOrTrait | SuperAccessorOrScala2x | SelfNameOrImplClass
+ Inline | LazyOrTrait | SuperAccessorOrScala2x | SelfNameOrImplClass
assert(FromStartFlags.isTermFlags && FromStartFlags.isTypeFlags)
// TODO: Should check that FromStartFlags do not change in completion
@@ -541,6 +541,9 @@ object Flags {
/** A type parameter with synthesized name */
final val ExpandedTypeParam = allOf(ExpandedName, TypeParam)
+ /** An inline method */
+ final val InlineMethod = allOf(Inline, Method)
+
/** A parameter or parameter accessor */
final val ParamOrAccessor = Param | ParamAccessor
diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala
index 9ef7caa68..c52264637 100644
--- a/src/dotty/tools/dotc/core/StdNames.scala
+++ b/src/dotty/tools/dotc/core/StdNames.scala
@@ -46,6 +46,7 @@ object StdNames {
final val IFkw: N = kw("if")
final val IMPLICITkw: N = kw("implicit")
final val IMPORTkw: N = kw("import")
+ final val INLINEkw: N = kw("inline")
final val LAZYkw: N = kw("lazy")
final val MACROkw: N = kw("macro")
final val MATCHkw: N = kw("match")
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index 86330f3ab..2fd79f999 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -275,21 +275,12 @@ object Parsers {
} finally inFunReturnType = saved
}
- private val isScala2Mode =
- ctx.settings.language.value.contains(nme.Scala2.toString)
-
def migrationWarningOrError(msg: String, offset: Int = in.offset) =
- if (isScala2Mode)
+ if (in.isScala2Mode)
ctx.migrationWarning(msg, source atPos Position(offset))
else
syntaxError(msg, offset)
- /** Cannot use ctx.featureEnabled because accessing the context would force too much */
- private def testScala2Mode(msg: String, pos: Position = Position(in.offset)) = {
- if (isScala2Mode) ctx.migrationWarning(msg, source atPos pos)
- isScala2Mode
- }
-
/* ---------- TREE CONSTRUCTION ------------------------------------------- */
/** Convert tree to formal parameter list
@@ -1467,6 +1458,7 @@ object Parsers {
case ABSTRACT => Abstract
case FINAL => Final
case IMPLICIT => ImplicitCommon
+ case INLINE => Inline
case LAZY => Lazy
case OVERRIDE => Override
case PRIVATE => Private
@@ -1570,7 +1562,10 @@ object Parsers {
/** Annotation ::= `@' SimpleType {ParArgumentExprs}
*/
def annot() =
- adjustStart(accept(AT)) { ensureApplied(parArgumentExprss(wrapNew(simpleType()))) }
+ adjustStart(accept(AT)) {
+ if (in.token == INLINE) in.token = BACKQUOTED_IDENT // allow for now
+ ensureApplied(parArgumentExprss(wrapNew(simpleType())))
+ }
def annotations(skipNewLines: Boolean = false): List[Tree] = {
if (skipNewLines) newLineOptWhenFollowedBy(AT)
@@ -1856,7 +1851,7 @@ object Parsers {
val toInsert =
if (in.token == LBRACE) s"$resultTypeStr ="
else ": Unit " // trailing space ensures that `def f()def g()` works.
- testScala2Mode(s"Procedure syntax no longer supported; `$toInsert' should be inserted here") && {
+ in.testScala2Mode(s"Procedure syntax no longer supported; `$toInsert' should be inserted here") && {
patch(source, Position(in.lastOffset), toInsert)
true
}
diff --git a/src/dotty/tools/dotc/parsing/Scanners.scala b/src/dotty/tools/dotc/parsing/Scanners.scala
index b46ab6348..a1a21583c 100644
--- a/src/dotty/tools/dotc/parsing/Scanners.scala
+++ b/src/dotty/tools/dotc/parsing/Scanners.scala
@@ -12,7 +12,7 @@ import scala.annotation.{ switch, tailrec }
import scala.collection.mutable
import mutable.ListBuffer
import Utility.isNameStart
-
+import rewrite.Rewrites.patch
object Scanners {
@@ -108,6 +108,7 @@ object Scanners {
target.token = toToken(idx)
}
}
+
def toToken(idx: Int): Token
/** Clear buffer and set string */
@@ -212,8 +213,22 @@ object Scanners {
/** A buffer for comments */
val commentBuf = new StringBuilder
+ private def handleMigration(keyword: Token): Token =
+ if (!isScala2Mode) keyword
+ else if (keyword == INLINE) treatAsIdent()
+ else keyword
+
+
+ private def treatAsIdent() = {
+ testScala2Mode(i"$name is now a keyword, put in `...` to keep as an identifier")
+ patch(source, Position(offset), "`")
+ patch(source, Position(offset + name.length), "`")
+ IDENTIFIER
+ }
+
def toToken(idx: Int): Token =
- if (idx >= 0 && idx <= lastKeywordStart) kwArray(idx) else IDENTIFIER
+ if (idx >= 0 && idx <= lastKeywordStart) handleMigration(kwArray(idx))
+ else IDENTIFIER
private class TokenData0 extends TokenData
@@ -235,6 +250,16 @@ object Scanners {
*/
var sepRegions: List[Token] = List()
+// Scala 2 compatibility
+
+ val isScala2Mode = ctx.settings.language.value.contains(nme.Scala2.toString)
+
+ /** Cannot use ctx.featureEnabled because accessing the context would force too much */
+ def testScala2Mode(msg: String, pos: Position = Position(offset)) = {
+ if (isScala2Mode) ctx.migrationWarning(msg, source atPos pos)
+ isScala2Mode
+ }
+
// Get next token ------------------------------------------------------------
/** Are we directly in a string interpolation expression?
diff --git a/src/dotty/tools/dotc/parsing/Tokens.scala b/src/dotty/tools/dotc/parsing/Tokens.scala
index b490cd133..5324207db 100644
--- a/src/dotty/tools/dotc/parsing/Tokens.scala
+++ b/src/dotty/tools/dotc/parsing/Tokens.scala
@@ -91,6 +91,7 @@ abstract class TokensCommon {
//final val LAZY = 59; enter(LAZY, "lazy")
//final val THEN = 60; enter(THEN, "then")
//final val FORSOME = 61; enter(FORSOME, "forSome") // TODO: deprecate
+ //final val INLINE = 62; enter(INLINE, "inline")
/** special symbols */
final val COMMA = 70; enter(COMMA, "','")
@@ -171,6 +172,7 @@ object Tokens extends TokensCommon {
final val LAZY = 59; enter(LAZY, "lazy")
final val THEN = 60; enter(THEN, "then")
final val FORSOME = 61; enter(FORSOME, "forSome") // TODO: deprecate
+ final val INLINE = 62; enter(INLINE, "inline")
/** special symbols */
final val NEWLINE = 78; enter(NEWLINE, "end of statement", "new line")
@@ -188,7 +190,7 @@ object Tokens extends TokensCommon {
/** XML mode */
final val XMLSTART = 96; enter(XMLSTART, "$XMLSTART$<") // TODO: deprecate
- final val alphaKeywords = tokenRange(IF, FORSOME)
+ final val alphaKeywords = tokenRange(IF, INLINE)
final val symbolicKeywords = tokenRange(USCORE, VIEWBOUND)
final val symbolicTokens = tokenRange(COMMA, VIEWBOUND)
final val keywords = alphaKeywords | symbolicKeywords
@@ -214,7 +216,7 @@ object Tokens extends TokensCommon {
final val defIntroTokens = templateIntroTokens | dclIntroTokens
final val localModifierTokens = BitSet(
- ABSTRACT, FINAL, SEALED, IMPLICIT, LAZY)
+ ABSTRACT, FINAL, SEALED, IMPLICIT, INLINE, LAZY)
final val accessModifierTokens = BitSet(
PRIVATE, PROTECTED)
diff --git a/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala b/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala
index 67aa24243..83c428976 100644
--- a/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala
+++ b/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala
@@ -22,7 +22,7 @@ object SyntaxHighlighting {
private def annotation(str: String) = AnnotationColor + str + NoColor
private val keywords: Seq[String] = for {
- index <- IF to FORSOME // All alpha keywords
+ index <- IF to INLINE // All alpha keywords
} yield tokenString(index)
private val interpolationPrefixes =
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 5e2ff4164..a33061453 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -562,11 +562,24 @@ class Namer { typer: Typer =>
protected def addAnnotations(denot: SymDenotation): Unit = original match {
case original: untpd.MemberDef =>
+ var hasInlineAnnot = false
for (annotTree <- untpd.modsDeco(original).mods.annotations) {
val cls = typedAheadAnnotation(annotTree)
val ann = Annotation.deferred(cls, implicit ctx => typedAnnotation(annotTree))
denot.addAnnotation(ann)
- if (cls == defn.InlineAnnot) addInlineInfo(denot, original)
+ if (cls == defn.InlineAnnot) {
+ hasInlineAnnot = true
+ addInlineInfo(denot, original)
+ }
+ }
+ if (!hasInlineAnnot && denot.is(InlineMethod)) {
+ // create a @inline annotation. Currently, the inlining trigger
+ // is really the annotation, not the flag. This is done so that
+ // we can still compile inline methods from Scala2x. Once we stop
+ // being compatible with Scala2 we should revise the logic to
+ // be based on the flag. Then creating a separate annotation becomes unnecessary.
+ denot.addAnnotation(Annotation(defn.InlineAnnot))
+ addInlineInfo(denot, original)
}
case _ =>
}
diff --git a/tests/neg/inlineAccess/C_1.scala b/tests/neg/inlineAccess/C_1.scala
index 6db1ea787..349f5b150 100644
--- a/tests/neg/inlineAccess/C_1.scala
+++ b/tests/neg/inlineAccess/C_1.scala
@@ -2,7 +2,6 @@ package p {
class C {
protected def f(): Unit = ()
- @inline
- def inl() = f() // error (when inlined): not accessible
+ inline def inl() = f() // error (when inlined): not accessible
}
}
diff --git a/tests/pos/rbtree.scala b/tests/pos/rbtree.scala
index 1401a1231..04c084596 100644
--- a/tests/pos/rbtree.scala
+++ b/tests/pos/rbtree.scala
@@ -430,12 +430,12 @@ object RedBlackTree {
* An alternative is to implement the these classes using plain old Java code...
*/
sealed abstract class Tree[A, +B](
- @(inline @getter) final val key: A,
- @(inline @getter) final val value: B,
- @(inline @getter) final val left: Tree[A, B],
- @(inline @getter) final val right: Tree[A, B])
+ @(`inline` @getter) final val key: A,
+ @(`inline` @getter) final val value: B,
+ @(`inline` @getter) final val left: Tree[A, B],
+ @(`inline` @getter) final val right: Tree[A, B])
extends Serializable {
- @(inline @getter) final val count: Int = 1 + RedBlackTree.count(left) + RedBlackTree.count(right)
+ @(`inline` @getter) final val count: Int = 1 + RedBlackTree.count(left) + RedBlackTree.count(right)
def black: Tree[A, B]
def red: Tree[A, B]
}
diff --git a/tests/run/inline/inlines_1.scala b/tests/run/inline/inlines_1.scala
index 8189e6805..24f1c78fe 100644
--- a/tests/run/inline/inlines_1.scala
+++ b/tests/run/inline/inlines_1.scala
@@ -5,8 +5,7 @@ object inlines {
final val monitored = false
- @inline
- def f(x: Int): Int = x * x
+ inline def f(x: Int): Int = x * x
val hits = new mutable.HashMap[String, Int] {
override def default(key: String): Int = 0
@@ -21,8 +20,7 @@ object inlines {
@volatile private var stack: List[String] = Nil
- @inline
- def track[T](fn: String)(op: => T) =
+ inline def track[T](fn: String)(op: => T) =
if (monitored) {
stack = fn :: stack
record(fn)
@@ -34,9 +32,9 @@ object inlines {
def f = "Outer.f"
class Inner {
val msg = " Inner"
- @inline def m = msg
- @inline def g = f
- @inline def h = f ++ m
+ inline def m = msg
+ inline def g = f
+ inline def h = f ++ m
}
val inner = new Inner
}
diff --git a/tests/run/inlineLazy.scala b/tests/run/inlineLazy.scala
deleted file mode 100644
index a8aa92498..000000000
--- a/tests/run/inlineLazy.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-class Test {
-
- lazy val x: Int = 33
-
- println(x)
-}
diff --git a/tests/run/inlinePower/power_1.scala b/tests/run/inlinePower/power_1.scala
index 23da6009a..4e96d7caa 100644
--- a/tests/run/inlinePower/power_1.scala
+++ b/tests/run/inlinePower/power_1.scala
@@ -2,8 +2,7 @@ package p
object pow {
- @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/run/inlinePrivates.scala b/tests/run/inlinePrivates.scala
index ade4592df..ce438ae8d 100644
--- a/tests/run/inlinePrivates.scala
+++ b/tests/run/inlinePrivates.scala
@@ -6,19 +6,19 @@ object Test {
private var y: T = _
- @inline def get1 = x
- @inline def get2[U](c: C[U]) = c.x
+ inline def get1 = x
+ inline def get2[U](c: C[U]) = c.x
- @inline def foo1(x: Int) = foo(x)
- @inline def foo2[U](c: C[U]) = c.foo(x)
+ inline def foo1(x: Int) = foo(x)
+ inline def foo2[U](c: C[U]) = c.foo(x)
- @inline def set1(z: T) = { y = z; y }
- @inline def set2[U](c: C[U]) = { c.y = c.x; c.y }
+ inline def set1(z: T) = { y = z; y }
+ inline def set2[U](c: C[U]) = { c.y = c.x; c.y }
}
object CC {
private val x = 3
- @inline def get1 = x
+ inline def get1 = x
}
def main(args: Array[String]) = {
@@ -29,24 +29,6 @@ object Test {
assert(cc.foo2(cc) == 2)
assert(cc.set1(3) == 3)
assert(cc.set2(cc) == 2)
-object Test {
-
- @inline
- def swap[T](x: T, x_= : T => Unit, y: T, y_= : T => Unit) = {
- val t = x
- x_=(y)
- y_=(t)
- }
-
- def main(args: Array[String]) = {
- var x = 1
- var y = 2
- @inline def setX(z: Int) = x = z
- @inline def setY(z: Int) = y = z
- swap[Int](x, setX, y, setY)
- assert(x == 2 && y == 1)
- }
-}
assert(CC.get1 == 3)
}
diff --git a/tests/run/inlinedAssign.scala b/tests/run/inlinedAssign.scala
index b9a5d287d..bb81aea26 100644
--- a/tests/run/inlinedAssign.scala
+++ b/tests/run/inlinedAssign.scala
@@ -1,6 +1,6 @@
object Test {
- @inline
+ @`inline`
def swap[T](x: T, x_= : T => Unit, y: T, y_= : T => Unit) = {
val t = x
x_=(y)
@@ -10,8 +10,8 @@ object Test {
def main(args: Array[String]) = {
var x = 1
var y = 2
- @inline def setX(z: Int) = x = z
- @inline def setY(z: Int) = y = z
+ @`inline` def setX(z: Int) = x = z
+ @`inline` def setY(z: Int) = y = z
swap[Int](x, setX, y, setY)
assert(x == 2 && y == 1)
}