diff options
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)) } |