summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/13-syntax-summary.md6
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala31
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala2
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala78
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala41
-rw-r--r--src/reflect/scala/reflect/internal/StdAttachments.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala1
-rw-r--r--test/files/neg/macro-invalidret.check2
-rw-r--r--test/files/neg/scopes.check2
-rw-r--r--test/files/neg/stmt-expr-discard.check4
-rw-r--r--test/files/neg/t1181.check6
-rw-r--r--test/files/neg/t9847.check45
-rw-r--r--test/files/neg/t9847.flags1
-rw-r--r--test/files/neg/t9847.scala23
-rw-r--r--test/files/neg/unit-returns-value.check6
-rw-r--r--test/files/run/contrib674.check5
-rw-r--r--test/files/run/contrib674.scala2
-rw-r--r--test/files/run/delay-bad.check4
-rw-r--r--test/files/run/delay-good.check4
-rw-r--r--test/files/run/exceptions-2.check2
-rw-r--r--test/files/run/lazy-locals.check4
-rw-r--r--test/files/run/macro-duplicate.check2
-rw-r--r--test/files/run/misc.check16
-rw-r--r--test/files/run/names-defaults.check5
-rw-r--r--test/files/run/patmatnew.check12
-rw-r--r--test/files/run/reify_lazyunit.check2
-rw-r--r--test/files/run/repl-bare-expr.check12
-rw-r--r--test/files/run/repl-no-imports-no-predef.check24
-rw-r--r--test/files/run/repl-parens.check12
-rw-r--r--test/files/run/t3488.check10
-rw-r--r--test/files/run/t4047.check8
-rw-r--r--test/files/run/t4680.check4
-rw-r--r--test/files/run/t5380.check4
-rw-r--r--test/files/run/t7047.check2
-rw-r--r--test/files/run/t7747-repl.check24
-rw-r--r--test/files/run/t8196.check2
-rw-r--r--test/files/run/try-2.check2
-rw-r--r--test/files/run/try.check2
-rw-r--r--test/files/specialized/tb3651.check2
-rw-r--r--test/files/specialized/tc3651.check2
-rw-r--r--test/files/specialized/td3651.check4
-rw-r--r--test/junit/scala/collection/mutable/OpenHashMapTest.scala2
-rw-r--r--test/junit/scala/lang/traits/BytecodeTest.scala29
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala6
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala4
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala14
49 files changed, 325 insertions, 163 deletions
diff --git a/spec/13-syntax-summary.md b/spec/13-syntax-summary.md
index a4b4aae570..44c481f9f6 100644
--- a/spec/13-syntax-summary.md
+++ b/spec/13-syntax-summary.md
@@ -132,7 +132,7 @@ grammar:
Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] `else' Expr]
| `while' `(' Expr `)' {nl} Expr
| `try' (`{' Block `}' | Expr) [`catch' `{' CaseClauses `}'] [`finally' Expr]
- | `do' Expr [semi] `while' `(' Expr ')'
+ | `do' Expr [semi] `while' `(' Expr `)'
| `for' (`(' Enumerators `)' | `{' Enumerators `}') {nl} [`yield'] Expr
| `throw' Expr
| `return' [Expr]
@@ -190,12 +190,12 @@ grammar:
| varid
| Literal
| StableId
- | StableId ‘(’ [Patterns ‘)’
+ | StableId ‘(’ [Patterns] ‘)’
| StableId ‘(’ [Patterns ‘,’] [varid ‘@’] ‘_’ ‘*’ ‘)’
| ‘(’ [Patterns] ‘)’
| XmlPattern
Patterns ::= Pattern [‘,’ Patterns]
- | ‘_’ *
+ | ‘_’ ‘*’
TypeParamClause ::= ‘[’ VariantTypeParam {‘,’ VariantTypeParam} ‘]’
FunTypeParamClause::= ‘[’ TypeParam {‘,’ TypeParam} ‘]’
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index 6f9682f434..bac84a4959 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -657,9 +657,13 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
} else if (isPrimitive(sym)) { // primitive method call
generatedType = genPrimitiveOp(app, expectedType)
} else { // normal method call
+ def isTraitSuperAccessorBodyCall = app.hasAttachment[UseInvokeSpecial.type]
val invokeStyle =
- if (sym.isStaticMember) InvokeStyle.Static
+ if (sym.isStaticMember)
+ InvokeStyle.Static
else if (sym.isPrivate || sym.isClassConstructor) InvokeStyle.Special
+ else if (isTraitSuperAccessorBodyCall)
+ InvokeStyle.Special
else InvokeStyle.Virtual
if (invokeStyle.hasInstance) genLoadQualifier(fun)
@@ -1077,7 +1081,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
assert(receiverClass == methodOwner, s"for super call, expecting $receiverClass == $methodOwner")
if (receiverClass.isTrait && !receiverClass.isJavaDefined) {
val staticDesc = MethodBType(typeToBType(method.owner.info) :: bmType.argumentTypes, bmType.returnType).descriptor
- val staticName = traitImplMethodName(method).toString
+ val staticName = traitSuperAccessorName(method).toString
bc.invokestatic(receiverName, staticName, staticDesc, isInterface, pos)
} else {
if (receiverClass.isTraitOrInterface) {
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
index e1decaba3e..18e7500172 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
@@ -52,7 +52,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
def needsStaticImplMethod(sym: Symbol) = sym.hasAttachment[global.mixer.NeedStaticImpl.type]
- final def traitImplMethodName(sym: Symbol): Name = {
+ final def traitSuperAccessorName(sym: Symbol): Name = {
val name = sym.javaSimpleName
if (sym.isMixinConstructor) name
else name.append(nme.NAME_JOIN_STRING)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
index 0dd6058f3e..dbad37cd5b 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
@@ -8,12 +8,12 @@ package scala.tools.nsc
package backend
package jvm
-import scala.collection.{ mutable, immutable }
+import scala.collection.{immutable, mutable}
import scala.tools.nsc.symtab._
-
import scala.tools.asm
import GenBCode._
import BackendReporting._
+import scala.tools.nsc.backend.jvm.BCodeHelpers.InvokeStyle
/*
*
@@ -490,18 +490,23 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
case dd : DefDef =>
val sym = dd.symbol
if (needsStaticImplMethod(sym)) {
- val staticDefDef = global.gen.mkStatic(dd, traitImplMethodName(sym), _.cloneSymbol)
- val forwarderDefDef = {
- val forwarderBody = Apply(global.gen.mkAttributedRef(staticDefDef.symbol), This(sym.owner).setType(sym.owner.typeConstructor) :: dd.vparamss.head.map(p => global.gen.mkAttributedIdent(p.symbol))).setType(sym.info.resultType)
- // we don't want to the optimizer to inline the static method into the forwarder. Instead,
- // the backend has a special case to transitively inline into a callsite of the forwarder
- // when the forwarder itself is inlined.
- forwarderBody.updateAttachment(NoInlineCallsiteAttachment)
- deriveDefDef(dd)(_ => global.atPos(dd.pos)(forwarderBody))
- }
- genDefDef(staticDefDef)
- if (!sym.isMixinConstructor)
+ if (sym.isMixinConstructor) {
+ val statified = global.gen.mkStatic(dd, sym.name, _.cloneSymbol)
+ genDefDef(statified)
+ } else {
+ val forwarderDefDef = {
+ val dd1 = global.gen.mkStatic(deriveDefDef(dd)(_ => EmptyTree), traitSuperAccessorName(sym), _.cloneSymbol)
+ dd1.symbol.setFlag(Flags.ARTIFACT).resetFlag(Flags.OVERRIDE)
+ val selfParam :: realParams = dd1.vparamss.head.map(_.symbol)
+ deriveDefDef(dd1)(_ =>
+ atPos(dd1.pos)(
+ Apply(Select(global.gen.mkAttributedIdent(selfParam).setType(sym.owner.typeConstructor), dd.symbol),
+ realParams.map(global.gen.mkAttributedIdent)).updateAttachment(UseInvokeSpecial))
+ )
+ }
genDefDef(forwarderDefDef)
+ genDefDef(dd)
+ }
} else genDefDef(dd)
case Template(_, _, body) => body foreach gen
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
index 477afaa91b..09e82de89b 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
@@ -596,7 +596,7 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
annotatedNoInline = methodSym.hasAnnotation(ScalaNoInlineClass))
if (needsStaticImplMethod(methodSym)) {
- val staticName = traitImplMethodName(methodSym).toString
+ val staticName = traitSuperAccessorName(methodSym).toString
val selfParam = methodSym.newSyntheticValueParam(methodSym.owner.typeConstructor, nme.SELF)
val staticMethodType = methodSym.info match {
case mt @ MethodType(params, res) => copyMethodType(mt, selfParam :: params, res)
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index 4d236b226d..dae8539c66 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -133,6 +133,7 @@ trait ScalaSettings extends AbsScalaSettings
val XnoPatmatAnalysis = BooleanSetting ("-Xno-patmat-analysis", "Don't perform exhaustivity/unreachability analysis. Also, ignore @switch annotation.")
val XfullLubs = BooleanSetting ("-Xfull-lubs", "Retains pre 2.10 behavior of less aggressive truncation of least upper bounds.")
+ val XgenMixinForwarders = BooleanSetting("-Xgen-mixin-forwarders", "Generate forwarder methods in classes inhering concrete methods from traits.")
// XML parsing options
object XxmlSettings extends MultiChoiceEnumeration {
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 6c8904f5d0..f781426f1a 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -243,43 +243,51 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
case NoSymbol =>
val isMemberOfClazz = clazz.info.findMember(member.name, 0, 0L, stableOnly = false).alternatives.contains(member)
if (isMemberOfClazz) {
- // `member` is a concrete method defined in `mixinClass`, which is a base class of
- // `clazz`, and the method is not overridden in `clazz`. A forwarder is needed if:
- //
- // - A non-trait base class of `clazz` defines a matching method. Example:
- // class C {def f: Int}; trait T extends C {def f = 1}; class D extends T
- // Even if C.f is abstract, the forwarder in D is needed, otherwise the JVM would
- // resolve `D.f` to `C.f`, see jvms-6.5.invokevirtual.
- //
- // - There exists another concrete, matching method in a parent interface `p` of
- // `clazz`, and the `mixinClass` does not itself extend `p`. In this case the
- // forwarder is needed to disambiguate. Example:
- // trait T1 {def f = 1}; trait T2 extends T1 {override def f = 2}; class C extends T2
- // In C we don't need a forwarder for f because T2 extends T1, so the JVM resolves
- // C.f to T2.f non-ambiguously. See jvms-5.4.3.3, "maximally-specific method".
- // trait U1 {def f = 1}; trait U2 {self:U1 => override def f = 2}; class D extends U2
- // In D the forwarder is needed, the interfaces U1 and U2 are unrelated at the JVM
- // level.
-
- @tailrec
- def existsCompetingMethod(baseClasses: List[Symbol]): Boolean = baseClasses match {
- case baseClass :: rest =>
- if (baseClass ne mixinClass) {
- val m = member.overriddenSymbol(baseClass)
- val isCompeting = m.exists && {
- !m.owner.isTraitOrInterface ||
- (!m.isDeferred && !mixinClass.isNonBottomSubClass(m.owner))
- }
- isCompeting || existsCompetingMethod(rest)
- } else existsCompetingMethod(rest)
-
- case _ => false
+ def genForwarder(): Unit = {
+ cloneAndAddMixinMember(mixinClass, member).asInstanceOf[TermSymbol] setAlias member
}
- if (existsCompetingMethod(clazz.baseClasses))
- cloneAndAddMixinMember(mixinClass, member).asInstanceOf[TermSymbol] setAlias member
- else if (!settings.nowarnDefaultJunitMethods && JUnitTestClass.exists && member.hasAnnotation(JUnitTestClass))
- warning(member.pos, "JUnit tests in traits that are compiled as default methods are not executed by JUnit 4. JUnit 5 will fix this issue.")
+ if (settings.XgenMixinForwarders) genForwarder()
+ else {
+
+ // `member` is a concrete method defined in `mixinClass`, which is a base class of
+ // `clazz`, and the method is not overridden in `clazz`. A forwarder is needed if:
+ //
+ // - A non-trait base class of `clazz` defines a matching method. Example:
+ // class C {def f: Int}; trait T extends C {def f = 1}; class D extends T
+ // Even if C.f is abstract, the forwarder in D is needed, otherwise the JVM would
+ // resolve `D.f` to `C.f`, see jvms-6.5.invokevirtual.
+ //
+ // - There exists another concrete, matching method in a parent interface `p` of
+ // `clazz`, and the `mixinClass` does not itself extend `p`. In this case the
+ // forwarder is needed to disambiguate. Example:
+ // trait T1 {def f = 1}; trait T2 extends T1 {override def f = 2}; class C extends T2
+ // In C we don't need a forwarder for f because T2 extends T1, so the JVM resolves
+ // C.f to T2.f non-ambiguously. See jvms-5.4.3.3, "maximally-specific method".
+ // trait U1 {def f = 1}; trait U2 {self:U1 => override def f = 2}; class D extends U2
+ // In D the forwarder is needed, the interfaces U1 and U2 are unrelated at the JVM
+ // level.
+
+ @tailrec
+ def existsCompetingMethod(baseClasses: List[Symbol]): Boolean = baseClasses match {
+ case baseClass :: rest =>
+ if (baseClass ne mixinClass) {
+ val m = member.overriddenSymbol(baseClass)
+ val isCompeting = m.exists && {
+ !m.owner.isTraitOrInterface ||
+ (!m.isDeferred && !mixinClass.isNonBottomSubClass(m.owner))
+ }
+ isCompeting || existsCompetingMethod(rest)
+ } else existsCompetingMethod(rest)
+
+ case _ => false
+ }
+
+ if (existsCompetingMethod(clazz.baseClasses))
+ genForwarder()
+ else if (!settings.nowarnDefaultJunitMethods && JUnitTestClass.exists && member.hasAnnotation(JUnitTestClass))
+ warning(member.pos, "JUnit tests in traits that are compiled as default methods are not executed by JUnit 4. JUnit 5 will fix this issue.")
+ }
}
case _ =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 130f2f9aa5..33cf5b9a09 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2437,13 +2437,36 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
}
val stats1 = if (isPastTyper) block.stats else
- block.stats.flatMap(stat => stat match {
+ block.stats.flatMap {
case vd@ValDef(_, _, _, _) if vd.symbol.isLazy =>
namer.addDerivedTrees(Typer.this, vd)
- case _ => stat::Nil
- })
- val stats2 = typedStats(stats1, context.owner)
+ case stat => stat::Nil
+ }
+ val stats2 = typedStats(stats1, context.owner, warnPure = false)
val expr1 = typed(block.expr, mode &~ (FUNmode | QUALmode), pt)
+
+ // sanity check block for unintended expr placement
+ if (!isPastTyper) {
+ val (count, result0, adapted) =
+ expr1 match {
+ case Block(expr :: Nil, Literal(Constant(()))) => (1, expr, true)
+ case Literal(Constant(())) => (0, EmptyTree, false)
+ case _ => (1, EmptyTree, false)
+ }
+ def checkPure(t: Tree, supple: Boolean): Unit =
+ if (treeInfo.isPureExprForWarningPurposes(t)) {
+ val msg = "a pure expression does nothing in statement position"
+ val parens = if (stats2.length + count > 1) "multiline expressions might require enclosing parentheses" else ""
+ val discard = if (adapted) "; a value can be silently discarded when Unit is expected" else ""
+ val text =
+ if (supple) s"${parens}${discard}"
+ else if (!parens.isEmpty) s"${msg}; ${parens}" else msg
+ context.warning(t.pos, text)
+ }
+ stats2.foreach(checkPure(_, supple = false))
+ if (result0.nonEmpty) checkPure(result0, supple = true)
+ }
+
treeCopy.Block(block, stats2, expr1)
.setType(if (treeInfo.isExprSafeToInline(block)) expr1.tpe else expr1.tpe.deconst)
} finally {
@@ -3018,7 +3041,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case _ => log("unhandled import: "+imp+" in "+unit); imp
}
- def typedStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = {
+ def typedStats(stats: List[Tree], exprOwner: Symbol, warnPure: Boolean = true): List[Tree] = {
val inBlock = exprOwner == context.owner
def includesTargetPos(tree: Tree) =
tree.pos.isRange && context.unit.exists && (tree.pos includes context.unit.targetPos)
@@ -3049,9 +3072,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
ConstructorsOrderError(stat)
}
}
- if (!isPastTyper && treeInfo.isPureExprForWarningPurposes(result)) context.warning(stat.pos,
- "a pure expression does nothing in statement position; you may be omitting necessary parentheses"
- )
+ if (warnPure && !isPastTyper && treeInfo.isPureExprForWarningPurposes(result)) {
+ val msg = "a pure expression does nothing in statement position"
+ val clause = if (stats.lengthCompare(1) > 0) "; multiline expressions may require enclosing parentheses" else ""
+ context.warning(stat.pos, s"${msg}${clause}")
+ }
result
}
diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala
index 76e34153c9..78f360409d 100644
--- a/src/reflect/scala/reflect/internal/StdAttachments.scala
+++ b/src/reflect/scala/reflect/internal/StdAttachments.scala
@@ -76,4 +76,6 @@ trait StdAttachments {
* in place of the outer parameter, can help callers to avoid capturing the outer instance.
*/
case object OuterArgCanBeElided extends PlainAttachment
+
+ case object UseInvokeSpecial extends PlainAttachment
}
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index caef5535b4..f55b33959a 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -46,6 +46,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.NoInlineCallsiteAttachment
this.InlineCallsiteAttachment
this.OuterArgCanBeElided
+ this.UseInvokeSpecial
this.noPrint
this.typeDebug
this.Range
diff --git a/test/files/neg/macro-invalidret.check b/test/files/neg/macro-invalidret.check
index ebdc8ec7da..a4d4fc6f34 100644
--- a/test/files/neg/macro-invalidret.check
+++ b/test/files/neg/macro-invalidret.check
@@ -27,7 +27,7 @@ java.lang.NullPointerException
Macros_Test_2.scala:15: error: macro implementation is missing
foo4
^
-Macros_Test_2.scala:17: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+Macros_Test_2.scala:17: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
foo6
^
two warnings found
diff --git a/test/files/neg/scopes.check b/test/files/neg/scopes.check
index f8e8c3758a..2db9678185 100644
--- a/test/files/neg/scopes.check
+++ b/test/files/neg/scopes.check
@@ -7,7 +7,7 @@ scopes.scala:5: error: x is already defined as value x
scopes.scala:8: error: y is already defined as value y
val y: Float = .0f
^
-scopes.scala:6: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+scopes.scala:6: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
{
^
scopes.scala:11: error: x is already defined as value x
diff --git a/test/files/neg/stmt-expr-discard.check b/test/files/neg/stmt-expr-discard.check
index 1207e6da50..4a80765365 100644
--- a/test/files/neg/stmt-expr-discard.check
+++ b/test/files/neg/stmt-expr-discard.check
@@ -1,7 +1,7 @@
-stmt-expr-discard.scala:3: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+stmt-expr-discard.scala:3: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
+ 2
^
-stmt-expr-discard.scala:4: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+stmt-expr-discard.scala:4: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
- 4
^
error: No warnings can be incurred under -Xfatal-warnings.
diff --git a/test/files/neg/t1181.check b/test/files/neg/t1181.check
index 13b73d5381..a9c102853d 100644
--- a/test/files/neg/t1181.check
+++ b/test/files/neg/t1181.check
@@ -1,10 +1,10 @@
-t1181.scala:8: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
- case (Nil, Nil) => map
- ^
t1181.scala:9: error: type mismatch;
found : scala.collection.immutable.Map[Symbol,Symbol]
required: Symbol
_ => buildMap(map.updated(keyList.head, valueList.head), keyList.tail, valueList.tail)
^
+t1181.scala:8: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
+ case (Nil, Nil) => map
+ ^
one warning found
one error found
diff --git a/test/files/neg/t9847.check b/test/files/neg/t9847.check
new file mode 100644
index 0000000000..e55109b3ef
--- /dev/null
+++ b/test/files/neg/t9847.check
@@ -0,0 +1,45 @@
+t9847.scala:4: warning: discarded non-Unit value
+ def f(): Unit = 42
+ ^
+t9847.scala:4: warning: a pure expression does nothing in statement position
+ def f(): Unit = 42
+ ^
+t9847.scala:5: warning: discarded non-Unit value
+ def g = (42: Unit)
+ ^
+t9847.scala:5: warning: a pure expression does nothing in statement position
+ def g = (42: Unit)
+ ^
+t9847.scala:7: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
+ 1
+ ^
+t9847.scala:12: warning: discarded non-Unit value
+ + 1
+ ^
+t9847.scala:12: warning: a pure expression does nothing in statement position
+ + 1
+ ^
+t9847.scala:11: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
+ 1
+ ^
+t9847.scala:12: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected
+ + 1
+ ^
+t9847.scala:16: warning: discarded non-Unit value
+ x + 1
+ ^
+t9847.scala:19: warning: discarded non-Unit value
+ def j(): Unit = x + 1
+ ^
+t9847.scala:21: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
+ class C { 42 }
+ ^
+t9847.scala:22: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
+ class D { 42 ; 17 }
+ ^
+t9847.scala:22: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
+ class D { 42 ; 17 }
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+14 warnings found
+one error found
diff --git a/test/files/neg/t9847.flags b/test/files/neg/t9847.flags
new file mode 100644
index 0000000000..065e3ca61e
--- /dev/null
+++ b/test/files/neg/t9847.flags
@@ -0,0 +1 @@
+-Xfatal-warnings -Ywarn-value-discard
diff --git a/test/files/neg/t9847.scala b/test/files/neg/t9847.scala
new file mode 100644
index 0000000000..51c16d815f
--- /dev/null
+++ b/test/files/neg/t9847.scala
@@ -0,0 +1,23 @@
+
+trait T {
+
+ def f(): Unit = 42
+ def g = (42: Unit)
+ def h = {
+ 1
+ + 1
+ }
+ def hh(): Unit = {
+ 1
+ + 1
+ }
+ def i(): Unit = {
+ val x = 1
+ x + 1
+ }
+ def x = 42
+ def j(): Unit = x + 1
+
+ class C { 42 }
+ class D { 42 ; 17 }
+}
diff --git a/test/files/neg/unit-returns-value.check b/test/files/neg/unit-returns-value.check
index f30a506ebe..7ebfbfde29 100644
--- a/test/files/neg/unit-returns-value.check
+++ b/test/files/neg/unit-returns-value.check
@@ -1,13 +1,13 @@
-unit-returns-value.scala:4: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+unit-returns-value.scala:4: warning: a pure expression does nothing in statement position
if (b) return 5
^
unit-returns-value.scala:4: warning: enclosing method f has result type Unit: return value discarded
if (b) return 5
^
-unit-returns-value.scala:22: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+unit-returns-value.scala:22: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
i1 // warn
^
-unit-returns-value.scala:23: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+unit-returns-value.scala:23: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
i2 // warn
^
error: No warnings can be incurred under -Xfatal-warnings.
diff --git a/test/files/run/contrib674.check b/test/files/run/contrib674.check
index 78325c1810..98c72f34dd 100644
--- a/test/files/run/contrib674.check
+++ b/test/files/run/contrib674.check
@@ -1,3 +1,6 @@
-contrib674.scala:15: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+contrib674.scala:15: warning: a pure expression does nothing in statement position
+ 1
+ ^
+contrib674.scala:15: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected
1
^
diff --git a/test/files/run/contrib674.scala b/test/files/run/contrib674.scala
index 45c9871fc4..bb9dad3686 100644
--- a/test/files/run/contrib674.scala
+++ b/test/files/run/contrib674.scala
@@ -1,7 +1,7 @@
// causes VerifyError with scala-2.5.1
object Test extends App {
- def bad() {
+ def bad(): Unit = {
try {
1
} catch {
diff --git a/test/files/run/delay-bad.check b/test/files/run/delay-bad.check
index fcd05c827f..bf41c79a3a 100644
--- a/test/files/run/delay-bad.check
+++ b/test/files/run/delay-bad.check
@@ -1,7 +1,7 @@
-delay-bad.scala:53: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+delay-bad.scala:53: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
f(new C { 5 })
^
-delay-bad.scala:73: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+delay-bad.scala:73: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
f(new { val x = 5 } with E() { 5 })
^
warning: there was one deprecation warning (since 2.11.0); re-run with -deprecation for details
diff --git a/test/files/run/delay-good.check b/test/files/run/delay-good.check
index b4f6b04af7..ed35b9225f 100644
--- a/test/files/run/delay-good.check
+++ b/test/files/run/delay-good.check
@@ -1,7 +1,7 @@
-delay-good.scala:53: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+delay-good.scala:53: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
f(new C { 5 })
^
-delay-good.scala:73: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+delay-good.scala:73: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
f(new { val x = 5 } with E() { 5 })
^
diff --git a/test/files/run/exceptions-2.check b/test/files/run/exceptions-2.check
index 4f8244800a..5cf5e71f41 100644
--- a/test/files/run/exceptions-2.check
+++ b/test/files/run/exceptions-2.check
@@ -1,4 +1,4 @@
-exceptions-2.scala:267: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+exceptions-2.scala:267: warning: a pure expression does nothing in statement position
try { 1 } catch { case e: java.io.IOException => () }
^
nested1:
diff --git a/test/files/run/lazy-locals.check b/test/files/run/lazy-locals.check
index 9e88a55d18..4565326bea 100644
--- a/test/files/run/lazy-locals.check
+++ b/test/files/run/lazy-locals.check
@@ -1,7 +1,7 @@
-lazy-locals.scala:153: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+lazy-locals.scala:153: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
{
^
-lazy-locals.scala:159: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+lazy-locals.scala:159: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
{
^
forced lazy val q
diff --git a/test/files/run/macro-duplicate.check b/test/files/run/macro-duplicate.check
index 58781b719a..7006b16611 100644
--- a/test/files/run/macro-duplicate.check
+++ b/test/files/run/macro-duplicate.check
@@ -1,3 +1,3 @@
-Test_2.scala:5: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+Test_2.scala:5: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
Macros.foo
^
diff --git a/test/files/run/misc.check b/test/files/run/misc.check
index 56116f8104..075dfeff2f 100644
--- a/test/files/run/misc.check
+++ b/test/files/run/misc.check
@@ -1,25 +1,25 @@
-misc.scala:46: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+misc.scala:46: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
42;
^
-misc.scala:47: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+misc.scala:47: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
42l;
^
-misc.scala:48: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+misc.scala:48: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
23.5f;
^
-misc.scala:49: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+misc.scala:49: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
23.5;
^
-misc.scala:50: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+misc.scala:50: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
"Hello";
^
-misc.scala:51: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+misc.scala:51: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
32 + 45;
^
-misc.scala:62: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+misc.scala:62: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
x;
^
-misc.scala:74: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+misc.scala:74: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
1 < 2;
^
### Hello
diff --git a/test/files/run/names-defaults.check b/test/files/run/names-defaults.check
index c358dc5849..722d28dd11 100644
--- a/test/files/run/names-defaults.check
+++ b/test/files/run/names-defaults.check
@@ -1,4 +1,7 @@
-names-defaults.scala:269: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+names-defaults.scala:269: warning: a pure expression does nothing in statement position
+ spawn(b = { val ttt = 1; ttt }, a = 0)
+ ^
+names-defaults.scala:269: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected
spawn(b = { val ttt = 1; ttt }, a = 0)
^
warning: there were four deprecation warnings; re-run with -deprecation for details
diff --git a/test/files/run/patmatnew.check b/test/files/run/patmatnew.check
index 56b8ac2f4f..117bc28c2d 100644
--- a/test/files/run/patmatnew.check
+++ b/test/files/run/patmatnew.check
@@ -1,10 +1,16 @@
-patmatnew.scala:351: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+patmatnew.scala:351: warning: a pure expression does nothing in statement position
case 1 => "OK"
^
-patmatnew.scala:352: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+patmatnew.scala:352: warning: a pure expression does nothing in statement position
case 2 => assert(false); "KO"
^
-patmatnew.scala:353: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+patmatnew.scala:352: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected
+ case 2 => assert(false); "KO"
+ ^
+patmatnew.scala:353: warning: a pure expression does nothing in statement position
+ case 3 => assert(false); "KO"
+ ^
+patmatnew.scala:353: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected
case 3 => assert(false); "KO"
^
patmatnew.scala:670: warning: This catches all Throwables. If this is really intended, use `case e : Throwable` to clear this warning.
diff --git a/test/files/run/reify_lazyunit.check b/test/files/run/reify_lazyunit.check
index 579ecfe8aa..e6acf5d17b 100644
--- a/test/files/run/reify_lazyunit.check
+++ b/test/files/run/reify_lazyunit.check
@@ -1,4 +1,4 @@
-reify_lazyunit.scala:6: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+reify_lazyunit.scala:6: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
lazy val x = { 0; println("12")}
^
12
diff --git a/test/files/run/repl-bare-expr.check b/test/files/run/repl-bare-expr.check
index e0a1f4ecd6..bdf8842bb0 100644
--- a/test/files/run/repl-bare-expr.check
+++ b/test/files/run/repl-bare-expr.check
@@ -1,12 +1,12 @@
scala> 2 ; 3
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
2 ;;
^
res0: Int = 3
scala> { 2 ; 3 }
-<console>:12: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:12: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
{ 2 ; 3 }
^
res1: Int = 3
@@ -15,16 +15,16 @@ scala> 5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Mooo
1 +
2 +
3 } ; bippy+88+11
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
defined object Cow
diff --git a/test/files/run/repl-no-imports-no-predef.check b/test/files/run/repl-no-imports-no-predef.check
index c2c8d21c0a..7c4ee82c78 100644
--- a/test/files/run/repl-no-imports-no-predef.check
+++ b/test/files/run/repl-no-imports-no-predef.check
@@ -76,13 +76,13 @@ y: Int = 13
scala>
scala> 2 ; 3
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
2 ;;
^
res14: Int = 3
scala> { 2 ; 3 }
-<console>:12: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:12: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
{ 2 ; 3 }
^
res15: Int = 3
@@ -92,16 +92,16 @@ bippy = {
1 +
2 +
3 } ; bippy+88+11
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def
^
defined object Cow
@@ -143,10 +143,10 @@ scala> ( (2 + 2 ) )
res24: Int = 4
scala> 5 ; ( (2 + 2 ) ) ; ((5))
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; ( (2 + 2 ) ) ;;
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; ( (2 + 2 ) ) ;;
^
res25: Int = 5
@@ -163,16 +163,16 @@ res28: String = 4423
scala>
scala> 55 ; ((2 + 2)) ; (1, 2, 3)
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
55 ; ((2 + 2)) ;;
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
55 ; ((2 + 2)) ;;
^
res29: (Int, Int, Int) = (1,2,3)
scala> 55 ; (x: scala.Int) => x + 1 ; () => ((5))
-<console>:12: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:12: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
55 ; (x: scala.Int) => x + 1 ;;
^
res30: () => Int = <function0>
@@ -183,7 +183,7 @@ scala> () => 5
res31: () => Int = <function0>
scala> 55 ; () => 5
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
55 ;;
^
res32: () => Int = <function0>
diff --git a/test/files/run/repl-parens.check b/test/files/run/repl-parens.check
index 6516f4ea90..477d4d462f 100644
--- a/test/files/run/repl-parens.check
+++ b/test/files/run/repl-parens.check
@@ -18,10 +18,10 @@ scala> ( (2 + 2 ) )
res5: Int = 4
scala> 5 ; ( (2 + 2 ) ) ; ((5))
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; ( (2 + 2 ) ) ;;
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; ( (2 + 2 ) ) ;;
^
res6: Int = 5
@@ -38,16 +38,16 @@ res9: String = 4423
scala>
scala> 55 ; ((2 + 2)) ; (1, 2, 3)
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
55 ; ((2 + 2)) ;;
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
55 ; ((2 + 2)) ;;
^
res10: (Int, Int, Int) = (1,2,3)
scala> 55 ; (x: Int) => x + 1 ; () => ((5))
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
55 ; (x: Int) => x + 1 ;;
^
res11: () => Int = <function0>
@@ -58,7 +58,7 @@ scala> () => 5
res12: () => Int = <function0>
scala> 55 ; () => 5
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
55 ;;
^
res13: () => Int = <function0>
diff --git a/test/files/run/t3488.check b/test/files/run/t3488.check
index 314dfc7838..75b2c3b07f 100644
--- a/test/files/run/t3488.check
+++ b/test/files/run/t3488.check
@@ -1,7 +1,13 @@
-t3488.scala:4: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+t3488.scala:4: warning: a pure expression does nothing in statement position
println(foo { val List(_*)=List(0); 1 } ())
^
-t3488.scala:5: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+t3488.scala:4: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected
+ println(foo { val List(_*)=List(0); 1 } ())
+ ^
+t3488.scala:5: warning: a pure expression does nothing in statement position
+ println(foo { val List(_*)=List(0); 1 } (1))
+ ^
+t3488.scala:5: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected
println(foo { val List(_*)=List(0); 1 } (1))
^
0
diff --git a/test/files/run/t4047.check b/test/files/run/t4047.check
index 3c41e6e244..c31f2f0858 100644
--- a/test/files/run/t4047.check
+++ b/test/files/run/t4047.check
@@ -1,13 +1,13 @@
-t4047.scala:23: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+t4047.scala:23: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
a.foo
^
-t4047.scala:24: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+t4047.scala:24: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
a.foo
^
-t4047.scala:26: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+t4047.scala:26: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
b.foo
^
-t4047.scala:27: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+t4047.scala:27: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
b.foo
^
Unit: called A.foo
diff --git a/test/files/run/t4680.check b/test/files/run/t4680.check
index 21c5f9e567..749ce4c627 100644
--- a/test/files/run/t4680.check
+++ b/test/files/run/t4680.check
@@ -1,7 +1,7 @@
-t4680.scala:51: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+t4680.scala:51: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
new C { 5 }
^
-t4680.scala:69: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+t4680.scala:69: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
new { val x = 5 } with E() { 5 }
^
warning: there was one deprecation warning (since 2.11.0); re-run with -deprecation for details
diff --git a/test/files/run/t5380.check b/test/files/run/t5380.check
index 731a798301..19471ac2d2 100644
--- a/test/files/run/t5380.check
+++ b/test/files/run/t5380.check
@@ -1,7 +1,7 @@
-t5380.scala:3: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+t5380.scala:3: warning: a pure expression does nothing in statement position
val f = () => return try { 1 } catch { case _: Throwable => 0 }
^
-t5380.scala:3: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+t5380.scala:3: warning: a pure expression does nothing in statement position
val f = () => return try { 1 } catch { case _: Throwable => 0 }
^
t5380.scala:3: warning: enclosing method main has result type Unit: return value discarded
diff --git a/test/files/run/t7047.check b/test/files/run/t7047.check
index 32bd581094..129ce3eeca 100644
--- a/test/files/run/t7047.check
+++ b/test/files/run/t7047.check
@@ -1,3 +1,3 @@
-Test_2.scala:2: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+Test_2.scala:2: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
Macros.foo
^
diff --git a/test/files/run/t7747-repl.check b/test/files/run/t7747-repl.check
index c5e92e9d79..621a70205e 100644
--- a/test/files/run/t7747-repl.check
+++ b/test/files/run/t7747-repl.check
@@ -15,13 +15,13 @@ scala> val z = x * y
z: Int = 156
scala> 2 ; 3
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
2 ;;
^
res0: Int = 3
scala> { 2 ; 3 }
-<console>:12: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:12: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
{ 2 ; 3 }
^
res1: Int = 3
@@ -30,16 +30,16 @@ scala> 5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Mooo
1 +
2 +
3 } ; bippy+88+11
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
defined object Cow
@@ -81,10 +81,10 @@ scala> ( (2 + 2 ) )
res10: Int = 4
scala> 5 ; ( (2 + 2 ) ) ; ((5))
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; ( (2 + 2 ) ) ;;
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
5 ; ( (2 + 2 ) ) ;;
^
res11: Int = 5
@@ -101,16 +101,16 @@ res14: String = 4423
scala>
scala> 55 ; ((2 + 2)) ; (1, 2, 3)
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
55 ; ((2 + 2)) ;;
^
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
55 ; ((2 + 2)) ;;
^
res15: (Int, Int, Int) = (1,2,3)
scala> 55 ; (x: Int) => x + 1 ; () => ((5))
-<console>:13: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:13: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
55 ; (x: Int) => x + 1 ;;
^
res16: () => Int = <function0>
@@ -121,7 +121,7 @@ scala> () => 5
res17: () => Int = <function0>
scala> 55 ; () => 5
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
55 ;;
^
res18: () => Int = <function0>
diff --git a/test/files/run/t8196.check b/test/files/run/t8196.check
index d11dc27e68..8a07ebb6d7 100644
--- a/test/files/run/t8196.check
+++ b/test/files/run/t8196.check
@@ -1,4 +1,4 @@
-t8196.scala:26: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+t8196.scala:26: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
form2.g1 // comment this line in order to make the test pass
^
warning: there were two feature warnings; re-run with -feature for details
diff --git a/test/files/run/try-2.check b/test/files/run/try-2.check
index 987d3462df..7fd45414da 100644
--- a/test/files/run/try-2.check
+++ b/test/files/run/try-2.check
@@ -1,4 +1,4 @@
-try-2.scala:41: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+try-2.scala:41: warning: a pure expression does nothing in statement position
10;
^
exception happened
diff --git a/test/files/run/try.check b/test/files/run/try.check
index f742ccb0df..d9521c2362 100644
--- a/test/files/run/try.check
+++ b/test/files/run/try.check
@@ -1,4 +1,4 @@
-try.scala:65: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+try.scala:65: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
1+1;
^
1 + 1 = 2
diff --git a/test/files/specialized/tb3651.check b/test/files/specialized/tb3651.check
index 8a3f686ef5..8e104f13ff 100644
--- a/test/files/specialized/tb3651.check
+++ b/test/files/specialized/tb3651.check
@@ -1,4 +1,4 @@
-tb3651.scala:8: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+tb3651.scala:8: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
lk.a
^
0
diff --git a/test/files/specialized/tc3651.check b/test/files/specialized/tc3651.check
index e2dbadf22c..1e56d196fd 100644
--- a/test/files/specialized/tc3651.check
+++ b/test/files/specialized/tc3651.check
@@ -1,4 +1,4 @@
-tc3651.scala:12: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+tc3651.scala:12: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
lk.a
^
0
diff --git a/test/files/specialized/td3651.check b/test/files/specialized/td3651.check
index 1a709fd0a7..697443ffe9 100644
--- a/test/files/specialized/td3651.check
+++ b/test/files/specialized/td3651.check
@@ -1,7 +1,7 @@
-td3651.scala:12: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+td3651.scala:12: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
b.a
^
-td3651.scala:16: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+td3651.scala:16: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
der.a
^
0
diff --git a/test/junit/scala/collection/mutable/OpenHashMapTest.scala b/test/junit/scala/collection/mutable/OpenHashMapTest.scala
index b6cddf2101..90f6be6ee5 100644
--- a/test/junit/scala/collection/mutable/OpenHashMapTest.scala
+++ b/test/junit/scala/collection/mutable/OpenHashMapTest.scala
@@ -1,6 +1,6 @@
package scala.collection.mutable
-import org.junit.Test
+import org.junit.{Ignore, Test}
import org.junit.Assert._
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/test/junit/scala/lang/traits/BytecodeTest.scala b/test/junit/scala/lang/traits/BytecodeTest.scala
index ec8508df99..e6c74b86ab 100644
--- a/test/junit/scala/lang/traits/BytecodeTest.scala
+++ b/test/junit/scala/lang/traits/BytecodeTest.scala
@@ -230,6 +230,35 @@ class BytecodeTest extends BytecodeTesting {
List(ALOAD, ILOAD, PUTFIELD, ALOAD, ACONST_NULL, "<init>", RETURN))
}
+ @Test
+ def mixinForwarders(): Unit = {
+ val code =
+ """trait T { def f = 1 }
+ |class C extends T
+ """.stripMargin
+ val List(c1, _) = compileClasses(code)
+ val List(c2, _) = newCompiler(extraArgs = "-Xgen-mixin-forwarders").compileClasses(code)
+ assert(getMethods(c1, "f").isEmpty)
+ assertSameCode(getMethod(c2, "f"),
+ List(VarOp(ALOAD, 0), Invoke(INVOKESTATIC, "T", "f$", "(LT;)I", true), Op(IRETURN)))
+ }
+
+ @Test
+ def sd143(): Unit = {
+ // this tests the status quo, which is wrong.
+ val code =
+ """class A { def m = 1 }
+ |class B extends A { override def m = 2 }
+ |trait T extends A
+ |class C extends B with T {
+ | override def m = super[T].m // should invoke A.m
+ |}
+ """.stripMargin
+ val List(_, _, c, _) = compileClasses(code)
+ // even though the bytecode refers to A.m, invokespecial will resolve to B.m
+ assertSameCode(getMethod(c, "m"),
+ List(VarOp(ALOAD, 0), Invoke(INVOKESPECIAL, "A", "m", "()I", false), Op(IRETURN)))
+ }
}
object invocationReceiversTestCode {
diff --git a/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala b/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala
index 5904cb2441..b09a41969e 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala
@@ -169,7 +169,7 @@ class BytecodeTest extends BytecodeTesting {
assertEquals(x.end, labels(7))
}
- @Test // wrong line numbers for rewritten `this` references in trait static methods
+ @Test
def sd186_traitLineNumber(): Unit = {
val code =
"""trait T {
@@ -182,9 +182,9 @@ class BytecodeTest extends BytecodeTesting {
val t = compileClass(code)
val tMethod = getMethod(t, "t$")
val invoke = Invoke(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false)
+ // ths static accessor is positioned at the line number of the accessed method.
assertSameCode(tMethod.instructions,
- List(Label(0), LineNumber(3, Label(0)), VarOp(ALOAD, 0), invoke, Op(POP),
- Label(5), LineNumber(4, Label(5)), VarOp(ALOAD, 0), invoke, Op(POP), Op(RETURN), Label(11))
+ List(Label(0), LineNumber(2, Label(0)), VarOp(ALOAD, 0), Invoke(INVOKESPECIAL, "T", "t", "()V", true), Op(RETURN), Label(4))
)
}
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala
index 85df42e069..a2513cacdc 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala
@@ -97,7 +97,7 @@ class InlinerSeparateCompilationTest {
""".stripMargin
val List(a, t) = compileClassesSeparately(List(codeA, assembly), args)
- assertNoInvoke(getMethod(t, "f$"))
- assertNoInvoke(getMethod(a, "n$"))
+ assertNoInvoke(getMethod(t, "f"))
+ assertNoInvoke(getMethod(a, "n"))
}
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
index 539c66a0d5..29a23df784 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
@@ -518,7 +518,7 @@ class InlinerTest extends BytecodeTesting {
val List(c, oMirror, oModule, t) = compile(code, allowMessage = i => {count += 1; i.msg contains warn})
assert(count == 1, count)
- assertNoInvoke(getMethod(t, "f$"))
+ assertNoInvoke(getMethod(t, "f"))
assertNoInvoke(getMethod(c, "t1"))
assertNoInvoke(getMethod(c, "t2"))
@@ -544,9 +544,9 @@ class InlinerTest extends BytecodeTesting {
val List(assembly, c, t) = compile(code)
- assertNoInvoke(getMethod(t, "f$"))
+ assertNoInvoke(getMethod(t, "f"))
- assertNoInvoke(getMethod(assembly, "n$"))
+ assertNoInvoke(getMethod(assembly, "n"))
assertNoInvoke(getMethod(c, "t1"))
assertNoInvoke(getMethod(c, "t2"))
@@ -622,8 +622,8 @@ class InlinerTest extends BytecodeTesting {
val List(ca, cb, t1, t2a, t2b) = compile(code, allowMessage = i => {count += 1; i.msg contains warning})
assert(count == 4, count) // see comments, f is not inlined 4 times
- assertNoInvoke(getMethod(t2a, "g2a$"))
- assertInvoke(getMethod(t2b, "g2b$"), "T1", "f")
+ assertNoInvoke(getMethod(t2a, "g2a"))
+ assertInvoke(getMethod(t2b, "g2b"), "T1", "f")
assertInvoke(getMethod(ca, "m1a"), "T1", "f")
assertNoInvoke(getMethod(ca, "m2a")) // no invoke, see comment on def g2a
@@ -682,8 +682,8 @@ class InlinerTest extends BytecodeTesting {
|}
""".stripMargin
val List(c, t) = compile(code)
- val t1 = getMethod(t, "t1$")
- val t2 = getMethod(t, "t2$")
+ val t1 = getMethod(t, "t1")
+ val t2 = getMethod(t, "t2")
val cast = TypeOp(CHECKCAST, "C")
Set(t1, t2).foreach(m => assert(m.instructions.contains(cast), m.instructions))
}