From 6cf73d0488bb42abd248519a6e9251df40378289 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Sun, 3 May 2020 01:26:32 -0700 Subject: [PATCH 1/6] Lint multiarg infix operand Lint multiarg infix applications `x op (a, b, c)` and also method definitions with multiple parameters where the method name is either an operator identifier or a plain identifier ending in an operator character. --- src/compiler/scala/tools/nsc/Reporting.scala | 1 + .../scala/tools/nsc/ast/parser/Parsers.scala | 43 +++++++++------ .../scala/tools/nsc/settings/Warnings.scala | 2 + .../scala/tools/nsc/typechecker/Typers.scala | 3 ++ .../reflect/internal/StdAttachments.scala | 3 ++ .../reflect/runtime/JavaUniverseForce.scala | 1 + test/files/jvm/stringbuilder.scala | 18 +++---- test/files/neg/sd503.check | 35 ++++++++++++ test/files/neg/sd503.scala | 53 +++++++++++++++++++ test/files/neg/t2641.check | 2 +- test/files/neg/t2641.scala | 2 +- test/files/run/collections.scala | 4 +- test/files/run/colltest1.scala | 4 +- test/files/run/indyLambdaKinds/Test_2.scala | 2 +- test/files/run/infix.check | 15 ++++++ test/files/run/synchronized.scala | 4 +- test/files/run/t2544.scala | 8 +-- test/files/run/t4813.scala | 4 +- test/files/run/t5045.scala | 4 +- test/files/run/t5565.check | 3 ++ test/files/run/t6271.scala | 2 +- test/files/run/t6731.scala | 2 +- test/files/run/t6827.scala | 2 +- test/files/run/t8433.scala | 4 +- 24 files changed, 171 insertions(+), 50 deletions(-) create mode 100644 test/files/neg/sd503.check create mode 100644 test/files/neg/sd503.scala create mode 100644 test/files/run/t5565.check diff --git a/src/compiler/scala/tools/nsc/Reporting.scala b/src/compiler/scala/tools/nsc/Reporting.scala index 2549f47ddbbd..eb892fa354cf 100644 --- a/src/compiler/scala/tools/nsc/Reporting.scala +++ b/src/compiler/scala/tools/nsc/Reporting.scala @@ -382,6 +382,7 @@ object Reporting { object LintBynameImplicit extends Lint; add(LintBynameImplicit) object LintRecurseWithDefault extends Lint; add(LintRecurseWithDefault) object LintUnitSpecialization extends Lint; add(LintUnitSpecialization) + object LintMultiargInfix extends Lint; add(LintMultiargInfix) sealed trait Feature extends WarningCategory { override def summaryCategory: WarningCategory = Feature } object Feature extends Feature { override def includes(o: WarningCategory): Boolean = o.isInstanceOf[Feature] }; add(Feature) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 51485239d1fa..c95d29f1aa7f 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -16,12 +16,11 @@ package scala.tools.nsc package ast.parser -import scala.collection.mutable -import mutable.ListBuffer -import scala.reflect.internal.{Precedence, ModifierFlags => Flags} +import scala.annotation.tailrec +import scala.collection.mutable, mutable.ListBuffer +import scala.reflect.internal.{Chars, ModifierFlags => Flags, Precedence} import scala.reflect.internal.util.{FreshNameCreator, ListOfNil, Position, SourceFile} import Tokens._ -import scala.annotation.tailrec import scala.tools.nsc.Reporting.WarningCategory /** Historical note: JavaParsers started life as a direct copy of Parsers @@ -868,11 +867,18 @@ self => } } } - def mkNamed(args: List[Tree]) = if (isExpr) args map treeInfo.assignmentToMaybeNamedArg else args + def mkNamed(args: List[Tree]) = if (isExpr) args.map(treeInfo.assignmentToMaybeNamedArg) else args + var isMultiarg = false val arguments = right match { - case Parens(Nil) => literalUnit :: Nil - case Parens(args) => mkNamed(args) - case _ => right :: Nil + case Parens(Nil) => literalUnit :: Nil + case Parens(args @ (_ :: Nil)) => mkNamed(args) + case Parens(args) => isMultiarg = true ; mkNamed(args) + case _ => right :: Nil + } + def mkApply(fun: Tree, args: List[Tree]) = { + val apply = Apply(fun, args) + if (isMultiarg) apply.updateAttachment(MultiargInfixAttachment) + apply } if (isExpr) { if (rightAssoc) { @@ -881,15 +887,12 @@ self => val liftedArg = atPos(left.pos) { ValDef(Modifiers(FINAL | SYNTHETIC | ARTIFACT), x, TypeTree(), stripParens(left)) } - Block( - liftedArg :: Nil, - Apply(mkSelection(right), List(Ident(x) setPos left.pos.focus))) - } else { - Apply(mkSelection(left), arguments) - } - } else { - Apply(Ident(op.encode), stripParens(left) :: arguments) - } + val apply = mkApply(mkSelection(right), List(Ident(x) setPos left.pos.focus)) + Block(liftedArg :: Nil, apply) + } else + mkApply(mkSelection(left), arguments) + } else + mkApply(Ident(op.encode), stripParens(left) :: arguments) } /* --------- OPERAND/OPERATOR STACK --------------------------------------- */ @@ -2796,6 +2799,12 @@ self => } expr() } + if (settings.multiargInfix) + vparamss match { + case (_ :: _ :: _) :: Nil if settings.multiargInfix && Chars.isOperatorPart(name.decoded.last) => + warning(nameOffset, "multiarg infix syntax looks like a tuple and will be deprecated", WarningCategory.LintMultiargInfix) + case _ => + } DefDef(newmods, name.toTermName, tparams, vparamss, restype, rhs) } signalParseProgress(result.pos) diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala index 7e97529fd22f..0db5589038f4 100644 --- a/src/compiler/scala/tools/nsc/settings/Warnings.scala +++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala @@ -192,6 +192,7 @@ trait Warnings { val ByNameImplicit = LintWarning("byname-implicit", "Block adapted by implicit with by-name parameter.") val RecurseWithDefault = LintWarning("recurse-with-default", "Recursive call used default argument.") val UnitSpecialization = LintWarning("unit-special", "Warn for specialization of Unit in parameter position.") + val MultiargInfix = LintWarning("multiarg-infix", "Infix operator was defined or used with multiarg operand.") def allLintWarnings = values.toSeq.asInstanceOf[Seq[LintWarning]] } @@ -223,6 +224,7 @@ trait Warnings { def warnByNameImplicit = lint contains ByNameImplicit def warnRecurseWithDefault = lint contains RecurseWithDefault def unitSpecialization = lint contains UnitSpecialization + def multiargInfix = lint contains MultiargInfix // The Xlint warning group. val lint = MultiChoiceSetting( diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index ecd9abf72283..07d1ffbc757a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -5127,6 +5127,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // The enclosing context may be case c @ C(_) => or val c @ C(_) = v. tree1 modifyType (_.finalResultType) tree1 + case tree1 @ Apply(_, args1) if tree.hasAttachment[MultiargInfixAttachment.type] && args1.lengthCompare(1) > 0 => + context.warning(tree1.pos, "multiarg infix syntax looks like a tuple and will be deprecated", WarningCategory.LintMultiargInfix) + tree1 case tree1 => tree1 } } diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala index 20e8f8bb218c..69d5c3c6ad2a 100644 --- a/src/reflect/scala/reflect/internal/StdAttachments.scala +++ b/src/reflect/scala/reflect/internal/StdAttachments.scala @@ -119,4 +119,7 @@ trait StdAttachments { class QualTypeSymAttachment(val sym: Symbol) case object ConstructorNeedsFence extends PlainAttachment + + /** Mark the syntax for linting purposes. */ + case object MultiargInfixAttachment extends PlainAttachment } diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index 20b82f0a6e8a..d65998a5a542 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -64,6 +64,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => this.TypeParamVarargsAttachment this.KnownDirectSubclassesCalled this.ConstructorNeedsFence + this.MultiargInfixAttachment this.noPrint this.typeDebug // inaccessible: this.posAssigner diff --git a/test/files/jvm/stringbuilder.scala b/test/files/jvm/stringbuilder.scala index 7a30c729eaae..46906e7568b8 100644 --- a/test/files/jvm/stringbuilder.scala +++ b/test/files/jvm/stringbuilder.scala @@ -30,7 +30,7 @@ Scala is a general purpose programming language designed to express common progr println("j2="+j2+", s2="+s2) println("s2.toString equals j2.toString = " + (s2.toString equals j2.toString)) - val j3 = j2; j3 setCharAt (0, j3 charAt 2) + val j3 = j2; j3.setCharAt(0, j3 charAt 2) val s3 = s2; s3(0) = s3(2) println("j3="+j3+", s3="+s3) println("s3.toString equals j3.toString = " + (s3.toString equals j3.toString)) @@ -57,15 +57,15 @@ object Test3 { def run(): Unit = { val j0 = new java.lang.StringBuilder("abc") val s0 = new StringBuilder("abc") - j0 insert (0, true) insert (0, 1.toByte) insert (0, 'a') insert (0, 88.toShort) insert (0, 9) insert (0, -1L) - s0 insert (0, true) insert (0, 1.toByte) insert (0, 'a') insert (0, 88.toShort) insert (0, 9) insert (0, -1L) + j0.insert(0, true).insert(0, 1.toByte).insert(0, 'a').insert(0, 88.toShort).insert(0, 9).insert(0, -1L) + s0.insert(0, true).insert(0, 1.toByte).insert(0, 'a').insert(0, 88.toShort).insert(0, 9).insert(0, -1L) println("j0="+j0+", s0="+s0) println("s0.toString equals j0.toString = " + (s0.toString equals j0.toString)) val j1 = new java.lang.StringBuilder val s1 = new StringBuilder - j1 insert (0, "###") insert (0, Array('0', '1', '2')) insert (0, "xyz".subSequence(0, 3)) - s1 insert (0, "###") insertAll (0, Array('0', '1', '2')) insertAll (0, List('x', 'y', 'z')) + j1.insert(0, "###").insert(0, Array('0', '1', '2')).insert(0, "xyz".subSequence(0, 3)) + s1.insert(0, "###").insertAll(0, Array('0', '1', '2')).insertAll(0, List('x', 'y', 'z')) println("j1="+j1+", s1="+s1) println("s1.toString equals j1.toString = " + (s1.toString equals j1.toString)) } @@ -76,13 +76,13 @@ object Test4 { val j0 = new java.lang.StringBuilder("abc") // Java 1.5+ val s0 = new StringBuilder("abc") - val j1 = j0 indexOf("c") - val s1 = s0 indexOf("c") + val j1 = j0.indexOf("c") + val s1 = s0.indexOf("c") println("j1="+j1+", s1="+s1) println("s1 == j1 = " + (s1 == j1)) - val j2 = j0 append "123abc" lastIndexOf("c") - val s2 = s0 append "123abc" lastIndexOf("c") + val j2 = j0.append("123abc").lastIndexOf("c") + val s2 = s0.append("123abc").lastIndexOf("c") println("j2="+j2+", s2="+s2) println("s2 == j2 = " + (s2 == j2)) } diff --git a/test/files/neg/sd503.check b/test/files/neg/sd503.check new file mode 100644 index 000000000000..99c909ce3c7d --- /dev/null +++ b/test/files/neg/sd503.check @@ -0,0 +1,35 @@ +sd503.scala:18: error: not enough arguments for method x_=: (i: Int, j: Int): Unit. +Unspecified value parameter j. + def f4() = c.x = (42, 27) // missing arg + ^ +sd503.scala:23: error: type mismatch; + found : (Int, Int) + required: Int + def f7() = d.x = (42, 27) // type mismatch (same as doti) + ^ +sd503.scala:9: warning: multiarg infix syntax looks like a tuple and will be deprecated + def % (i: Int, j: Int) = i + j // operator, warn + ^ +sd503.scala:29: warning: multiarg infix syntax looks like a tuple and will be deprecated + def x_=(i: Int, j: Int): Unit = value = i + j // multiarg, warn + ^ +sd503.scala:34: warning: multiarg infix syntax looks like a tuple and will be deprecated + def x_=(i: Int, j: Int = 1): Unit = devalue = i + j // multiarg, warn + ^ +sd503.scala:47: warning: multiarg infix syntax looks like a tuple and will be deprecated + def +=(x: A, y: A, zs: A*): this.type = addAll(x +: y +: zs) // very multiarg, warn + ^ +sd503.scala:13: warning: multiarg infix syntax looks like a tuple and will be deprecated + def f1(t: T) = t m (1, 2) // multiarg, warn + ^ +sd503.scala:15: warning: multiarg infix syntax looks like a tuple and will be deprecated + def f3(t: T) = t % (1, 2) // multiarg, warn + ^ +sd503.scala:19: warning: multiarg infix syntax looks like a tuple and will be deprecated + def f5() = c x_= (42, 27) // multiarg, warn + ^ +sd503.scala:52: warning: multiarg infix syntax looks like a tuple and will be deprecated + def f[A](as: Embiggen[A], x: A, y: A, z: A): as.type = as += (x, y, z) // very multiarg, warn + ^ +8 warnings +2 errors diff --git a/test/files/neg/sd503.scala b/test/files/neg/sd503.scala new file mode 100644 index 000000000000..21a41e70f42a --- /dev/null +++ b/test/files/neg/sd503.scala @@ -0,0 +1,53 @@ +// scalac: -Xlint:multiarg-infix +// +// lint multiarg infix syntax, e.g., vs += (1, 2, 3) +// Since infix is encouraged by symbolic operator names, discourage defining def += (x: A, y: A, zs: A*) + +trait T { + def m(i: Int, j: Int) = i + j + + def % (i: Int, j: Int) = i + j // operator, warn + + + def f0(t: T) = t.m(1, 2) // ok + def f1(t: T) = t m (1, 2) // multiarg, warn + def f2(t: T) = t.%(1, 2) // ok + def f3(t: T) = t % (1, 2) // multiarg, warn + + def c = new C + def f4() = c.x = (42, 27) // missing arg + def f5() = c x_= (42, 27) // multiarg, warn + + def d = new D + def f6() = d.x = 42 // ok! + def f7() = d.x = (42, 27) // type mismatch (same as doti) +} + +class C { + private var value: Int = _ + def x: Int = value + def x_=(i: Int, j: Int): Unit = value = i + j // multiarg, warn +} +class D { + private var devalue: Int = _ // d.value + def x: Int = devalue + def x_=(i: Int, j: Int = 1): Unit = devalue = i + j // multiarg, warn +} + +// If the application is adapted such that what looks like a tuple is taken as a tuple, +// then don't warn; eventually this will be normal behavior. +trait OK { + def f(p: (Int, Int)) = p == (42, 17) // nowarn! + def g(ps: Embiggen[(Int, Int)]) = ps :+ (42, 17) // nowarn! +} + +// Growable is the paradigmatic example +trait Embiggen[A] { + def addAll(as: Seq[A]): this.type + def +=(x: A, y: A, zs: A*): this.type = addAll(x +: y +: zs) // very multiarg, warn + def :+(a: A): Embiggen[A] +} + +trait NotOK { + def f[A](as: Embiggen[A], x: A, y: A, z: A): as.type = as += (x, y, z) // very multiarg, warn +} diff --git a/test/files/neg/t2641.check b/test/files/neg/t2641.check index 15a626af3532..1da33ba0d8f9 100644 --- a/test/files/neg/t2641.check +++ b/test/files/neg/t2641.check @@ -2,6 +2,6 @@ t2641.scala:22: error: wrong number of type arguments for ManagedSeq, should be with TraversableViewLike[A, ManagedSeqStrict[A], ManagedSeq[A]] ^ t2641.scala:28: error: value managedIterator is not a member of ManagedSeq[A,Coll] - override def managedIterator = self.managedIterator slice (0, 0) + override def managedIterator = self.managedIterator.slice(0, 0) ^ 2 errors diff --git a/test/files/neg/t2641.scala b/test/files/neg/t2641.scala index 5801c245698a..db89a4ff68fe 100644 --- a/test/files/neg/t2641.scala +++ b/test/files/neg/t2641.scala @@ -25,7 +25,7 @@ trait ManagedSeq[+A, +Coll] trait Transformed[+B] extends ManagedSeq[B, Coll] with super.Transformed[B] trait Sliced extends Transformed[A] with super.Sliced { - override def managedIterator = self.managedIterator slice (0, 0) + override def managedIterator = self.managedIterator.slice(0, 0) } } diff --git a/test/files/run/collections.scala b/test/files/run/collections.scala index 516d3e038601..7b0b0420301f 100644 --- a/test/files/run/collections.scala +++ b/test/files/run/collections.scala @@ -35,7 +35,7 @@ object Test extends App { println("***** "+msg+":") var s = s0 s = s.clone() += 2 - s = s.clone += (3, 4000, 10000) + s = s.clone.+=(3, 4000, 10000) println("test1: "+sum(s)) time { s = s ++ (List.range(0, iters) map (2*)) @@ -88,7 +88,7 @@ object Test extends App { println("***** "+msg+":") var s = s0 s = s.clone() += (2 -> 2) - s = s.clone() += (3 -> 3, 4000 -> 4000, 10000 -> 10000) + s = s.clone().+=(3 -> 3, 4000 -> 4000, 10000 -> 10000) println("test1: "+sum(s map (_._2))) time { s = s ++ (List.range(0, iters) map (x => x * 2 -> x * 2)) diff --git a/test/files/run/colltest1.scala b/test/files/run/colltest1.scala index d34547e7f25d..d2a98c728a31 100644 --- a/test/files/run/colltest1.scala +++ b/test/files/run/colltest1.scala @@ -47,8 +47,8 @@ object Test extends App { assert(vs1 == ten) assert((ten take 5) == firstFive) assert((ten drop 5) == secondFive) - assert(ten slice (3, 3) isEmpty) - assert((ten slice (3, 6)) == List(4, 5, 6), ten slice (3, 6)) + assert(ten.slice(3, 3).isEmpty) + assert((ten.slice(3, 6)) == List(4, 5, 6), ten.slice(3, 6)) assert((ten takeWhile (_ <= 5)) == firstFive) assert((ten dropWhile (_ <= 5)) == secondFive) assert((ten span (_ <= 5)) == (firstFive, secondFive)) diff --git a/test/files/run/indyLambdaKinds/Test_2.scala b/test/files/run/indyLambdaKinds/Test_2.scala index d876dd5fd72b..55274d4f4484 100644 --- a/test/files/run/indyLambdaKinds/Test_2.scala +++ b/test/files/run/indyLambdaKinds/Test_2.scala @@ -49,7 +49,7 @@ object Test extends DirectTest { override def show(): Unit = { compile() - ScalaClassLoader(getClass.getClassLoader) run ("Main", Nil) + ScalaClassLoader(getClass.getClassLoader).run("Main", Nil) } } diff --git a/test/files/run/infix.check b/test/files/run/infix.check index dd0457b7769d..606e49da0d43 100644 --- a/test/files/run/infix.check +++ b/test/files/run/infix.check @@ -1,2 +1,17 @@ +infix.scala:6: warning: multiarg infix syntax looks like a tuple and will be deprecated + val xs = new op(null, 0, 0) op (1, 1) op (2, 2) + ^ +infix.scala:6: warning: multiarg infix syntax looks like a tuple and will be deprecated + val xs = new op(null, 0, 0) op (1, 1) op (2, 2) + ^ +infix.scala:9: warning: multiarg infix syntax looks like a tuple and will be deprecated + case null op (0, 0) op (1, 1) op (2, 2) => Console.println("OK") + ^ +infix.scala:9: warning: multiarg infix syntax looks like a tuple and will be deprecated + case null op (0, 0) op (1, 1) op (2, 2) => Console.println("OK") + ^ +infix.scala:9: warning: multiarg infix syntax looks like a tuple and will be deprecated + case null op (0, 0) op (1, 1) op (2, 2) => Console.println("OK") + ^ op(op(op(null,0,0),1,1),2,2) OK diff --git a/test/files/run/synchronized.scala b/test/files/run/synchronized.scala index 27fd6356bb6e..06966adf8599 100644 --- a/test/files/run/synchronized.scala +++ b/test/files/run/synchronized.scala @@ -328,9 +328,7 @@ class C2 extends T object O2 extends T object Test extends App { - def check(name: String, result: Boolean): Unit = { - println("%-10s %s" format (name +":", if (result) "OK" else "FAILED")) - } + def check(name: String, result: Boolean): Unit = println("%-10s %s".format(name +":", if (result) "OK" else "FAILED")) val c1 = new C1 check("c1.f1", c1.f1) diff --git a/test/files/run/t2544.scala b/test/files/run/t2544.scala index 6bee2f108230..1ae9c7f148a2 100644 --- a/test/files/run/t2544.scala +++ b/test/files/run/t2544.scala @@ -11,10 +11,10 @@ object Test { ) def main(args: Array[String]) = { - println(Foo indexWhere(_ >= 2,1)) - println(Foo.toList indexWhere(_ >= 2,1)) - println(Foo segmentLength(_ <= 3,1)) - println(Foo.toList segmentLength(_ <= 3,1)) + println(Foo.indexWhere(_ >= 2,1)) + println(Foo.toList.indexWhere(_ >= 2,1)) + println(Foo.segmentLength(_ <= 3,1)) + println(Foo.toList.segmentLength(_ <= 3,1)) lengthEquiv(Foo lengthCompare 7) lengthEquiv(Foo.toList lengthCompare 7) lengthEquiv(Foo lengthCompare 2) diff --git a/test/files/run/t4813.scala b/test/files/run/t4813.scala index e6e65ffa41d5..fdf14ebdb07b 100644 --- a/test/files/run/t4813.scala +++ b/test/files/run/t4813.scala @@ -26,6 +26,6 @@ object Test extends App { runTest(TreeSet(1,2,3))(_.clone) { buf => buf add 4 } // Maps - runTest(HashMap(1->1,2->2,3->3))(_.clone) { buf => buf put (4,4) } - runTest(WeakHashMap(1->1,2->2,3->3))(_.clone) { buf => buf put (4,4) } + runTest(HashMap(1->1,2->2,3->3))(_.clone)(_.put(4,4)) + runTest(WeakHashMap(1->1,2->2,3->3))(_.clone)(_.put(4,4)) } diff --git a/test/files/run/t5045.scala b/test/files/run/t5045.scala index b0c3a4ddc4f4..a539e3a4cb19 100644 --- a/test/files/run/t5045.scala +++ b/test/files/run/t5045.scala @@ -1,12 +1,10 @@ -import scala.language.postfixOps - object Test extends App { import scala.util.matching.{ Regex, UnanchoredRegex } val dateP1 = """(\d\d\d\d)-(\d\d)-(\d\d)""".r.unanchored - val dateP2 = """(\d\d\d\d)-(\d\d)-(\d\d)""" r ("year", "month", "day") unanchored + val dateP2 = """(\d\d\d\d)-(\d\d)-(\d\d)""".r("year", "month", "day").unanchored val dateP3 = new Regex("""(\d\d\d\d)-(\d\d)-(\d\d)""", "year", "month", "day") with UnanchoredRegex val yearStr = "2011" diff --git a/test/files/run/t5565.check b/test/files/run/t5565.check new file mode 100644 index 000000000000..d73da88b3e7a --- /dev/null +++ b/test/files/run/t5565.check @@ -0,0 +1,3 @@ +t5565.scala:10: warning: multiarg infix syntax looks like a tuple and will be deprecated + assert(math.abs(-4.0) ~== (4.0, 0.001)) + ^ diff --git a/test/files/run/t6271.scala b/test/files/run/t6271.scala index 5c7a97b04746..f0539fbce743 100644 --- a/test/files/run/t6271.scala +++ b/test/files/run/t6271.scala @@ -21,7 +21,7 @@ object Test extends App { } def slicedIssue = { val viewed : Iterable[Iterable[Int]] = List(List(0).view).view - val filtered = viewed flatMap { x => List( x slice (2,3) ) } + val filtered = viewed.flatMap(x => List(x.slice(2,3))) filtered.iterator.to(Iterable).flatten } filterIssue diff --git a/test/files/run/t6731.scala b/test/files/run/t6731.scala index 82b77852cac4..8ea4962558dc 100644 --- a/test/files/run/t6731.scala +++ b/test/files/run/t6731.scala @@ -5,7 +5,7 @@ import scala.reflect.{ ClassTag, classTag } object Util { def show[T](x: T): T = { println(x) ; x } - def mkArgs(xs: Any*) = xs map { case ((k, v)) => s"$k=$v" ; case x => "" + x } mkString ("(", ", ", ")") + def mkArgs(xs: Any*) = xs.map { case ((k, v)) => s"$k=$v" ; case x => "" + x }.mkString("(", ", ", ")") } import Util._ diff --git a/test/files/run/t6827.scala b/test/files/run/t6827.scala index f2dd7282d590..cf4dd78295a7 100644 --- a/test/files/run/t6827.scala +++ b/test/files/run/t6827.scala @@ -10,7 +10,7 @@ object Test extends App { } catch { case e: Exception => e.toString } - println("%s: %s" format (label, status)) + println(s"$label: $status") } tryit("start at -5", -5, 10) diff --git a/test/files/run/t8433.scala b/test/files/run/t8433.scala index 0e8043aa367f..16144ffddb7c 100644 --- a/test/files/run/t8433.scala +++ b/test/files/run/t8433.scala @@ -37,9 +37,9 @@ object Test extends DirectTest { val g = newCompiler() assert(compileString(g)(code)) - ScalaClassLoader(getClass.getClassLoader) run ("Main", Nil) + ScalaClassLoader(getClass.getClassLoader).run("Main", Nil) assert(compileString(g)(code)) - ScalaClassLoader(getClass.getClassLoader) run ("Main", Nil) + ScalaClassLoader(getClass.getClassLoader).run("Main", Nil) } override def extraSettings = s"-usejavacp -d ${testOutput.path} -cp ${testOutput.path}" From cd6d4a1d282e955efeeded7e5e76634ee943225a Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Sun, 3 May 2020 22:35:47 -0700 Subject: [PATCH 2/6] Reduce multiarg infix applications --- build.sbt | 1 + .../reflect/macros/compiler/Errors.scala | 2 +- .../reflect/reify/utils/SymbolTables.scala | 1 + src/compiler/scala/tools/nsc/Reporting.scala | 2 +- .../scala/tools/nsc/ast/TreeGen.scala | 2 +- .../scala/tools/nsc/ast/parser/Parsers.scala | 18 ++--- .../tools/nsc/symtab/SymbolTrackers.scala | 2 +- .../tools/nsc/transform/Constructors.scala | 14 ++-- .../nsc/transform/ExtensionMethods.scala | 6 +- .../tools/nsc/transform/SpecializeTypes.scala | 2 +- .../scala/tools/nsc/transform/TailCalls.scala | 2 +- .../tools/nsc/transform/patmat/Logic.scala | 10 +-- .../nsc/transform/patmat/MatchAnalysis.scala | 8 +-- .../transform/patmat/PatternMatching.scala | 2 +- .../tools/nsc/typechecker/NamesDefaults.scala | 2 +- .../nsc/typechecker/SuperAccessors.scala | 2 +- .../nsc/typechecker/TypeDiagnostics.scala | 10 +-- .../scala/tools/nsc/typechecker/Typers.scala | 2 +- .../scala/tools/reflect/ToolBoxFactory.scala | 2 +- .../scala/tools/nsc/interactive/Global.scala | 4 +- src/library/scala/runtime/ScalaRunTime.scala | 12 ++-- .../scala/tools/partest/DirectTest.scala | 7 +- .../scala/tools/partest/nest/Runner.scala | 12 ++-- src/partest/scala/tools/partest/package.scala | 5 +- .../reflect/internal/AnnotationInfos.scala | 2 +- .../scala/reflect/internal/Definitions.scala | 2 +- .../scala/reflect/internal/Kinds.scala | 2 +- .../scala/reflect/internal/Mirrors.scala | 2 +- .../scala/reflect/internal/Symbols.scala | 5 +- .../reflect/internal/TypeDebugging.scala | 4 +- .../scala/reflect/internal/Types.scala | 12 ++-- .../reflect/internal/transform/Erasure.scala | 2 +- .../reflect/internal/util/Position.scala | 2 +- .../scala/reflect/runtime/JavaMirrors.scala | 10 +-- .../nsc/interpreter/shell/JavapClass.scala | 4 +- .../nsc/interpreter/shell/Scripted.scala | 2 +- .../scala/tools/nsc/interpreter/IMain.scala | 2 +- .../tools/nsc/doc/model/ModelFactory.scala | 2 +- .../immutable/HashMapBulkBenchmark.scala | 2 +- .../immutable/MapAppendBenchmark.scala | 4 +- .../junit/scala/collection/IteratorTest.scala | 22 ++++--- .../collection/SetMapConsistencyTest.scala | 12 ++-- .../collection/immutable/IndexedSeqTest.scala | 66 +++++++++---------- .../collection/mutable/ArrayDequeTest.scala | 2 +- .../mutable/CollisionProofHashMapTest.scala | 2 +- test/junit/scala/io/SourceTest.scala | 2 +- test/scalacheck/range.scala | 6 +- 47 files changed, 146 insertions(+), 155 deletions(-) diff --git a/build.sbt b/build.sbt index d25a5539b9ed..05999917524d 100644 --- a/build.sbt +++ b/build.sbt @@ -374,6 +374,7 @@ lazy val commonSettings = instanceSettings ++ clearSourceAndResourceDirectories connectInput in run := true, //scalacOptions in Compile += "-Xlint:-deprecation,-inaccessible,-nonlocal-return,-valpattern,_", //scalacOptions in Compile ++= Seq("-Xmaxerrs", "5", "-Xmaxwarns", "5"), + scalacOptions in Compile += "-Wconf:cat=unchecked&msg=The outer reference in this type test cannot be checked at run time.:ws", scalacOptions in Compile in doc ++= Seq( "-doc-footer", "epfl", "-diagrams", diff --git a/src/compiler/scala/reflect/macros/compiler/Errors.scala b/src/compiler/scala/reflect/macros/compiler/Errors.scala index afbf2f2bb680..301d90ddec18 100644 --- a/src/compiler/scala/reflect/macros/compiler/Errors.scala +++ b/src/compiler/scala/reflect/macros/compiler/Errors.scala @@ -100,7 +100,7 @@ trait Errors extends Traces { private def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean, untype: Boolean) = { def preprocess(tpe: Type) = if (untype) untypeMetalevel(tpe) else tpe - var pssPart = (pss map (ps => ps map (p => p.defStringSeenAs(preprocess(p.info))) mkString ("(", ", ", ")"))).mkString + var pssPart = pss.map(_.map(p => p.defStringSeenAs(preprocess(p.info))).mkString("(", ", ", ")")).mkString if (abbreviate) pssPart = abbreviateCoreAliases(pssPart) var retPart = preprocess(restpe).toString if (abbreviate || macroDdef.tpt.tpe == null) retPart = abbreviateCoreAliases(retPart) diff --git a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala index 034b2b89f1d7..372474a5768a 100644 --- a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala +++ b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala @@ -58,6 +58,7 @@ trait SymbolTables { case None => EmptyTree } + @deprecated("use add instead", since="2.13.3") def +(sym: Symbol, name: TermName, reification: Tree): SymbolTable = add(sym, name, reification) def +(symDef: Tree): SymbolTable = add(symDef) def ++(symDefs: IterableOnce[Tree]): SymbolTable = symDefs.iterator.foldLeft(this)((symtab, symDef) => symtab.add(symDef)) diff --git a/src/compiler/scala/tools/nsc/Reporting.scala b/src/compiler/scala/tools/nsc/Reporting.scala index eb892fa354cf..ab4355217553 100644 --- a/src/compiler/scala/tools/nsc/Reporting.scala +++ b/src/compiler/scala/tools/nsc/Reporting.scala @@ -229,7 +229,7 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio ) reportedFeature += featureTrait - val msg = s"$featureDesc $req be enabled\nby making the implicit value $fqname visible.$explain" replace ("#", construct) + val msg = s"$featureDesc $req be enabled\nby making the implicit value $fqname visible.$explain".replace("#", construct) // maybe pos.source.file.file.getParentFile.getName or Path(source.file.file).parent.name def parentFileName(source: internal.util.SourceFile) = Option(java.nio.file.Paths.get(source.path).getParent).map(_.getFileName.toString) diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index 64430eacd2e0..5e72cc1cbec6 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -364,7 +364,7 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL { } def expandFunction(localTyper: analyzer.Typer)(fun: Function, inConstructorFlag: Long): Tree = { - val anonClass = fun.symbol.owner newAnonymousFunctionClass(fun.pos, inConstructorFlag) + val anonClass = fun.symbol.owner.newAnonymousFunctionClass(fun.pos, inConstructorFlag) val parents = if (isFunctionType(fun.tpe)) { anonClass addAnnotation SerialVersionUIDAnnotation addSerializable(abstractFunctionType(fun.vparams.map(_.symbol.tpe), fun.body.tpe.deconst)) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index c95d29f1aa7f..a04bb85bdb5d 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2187,7 +2187,7 @@ self => private def addMod(mods: Modifiers, mod: Long, pos: Position): Modifiers = { if (mods hasFlag mod) syntaxError(in.offset, "repeated modifier", skipIt = false) in.nextToken() - (mods | mod) withPosition (mod, pos) + (mods | mod).withPosition(mod, pos) } private def tokenRange(token: TokenData) = @@ -2397,7 +2397,7 @@ self => if (mods.isLazy) syntaxError("lazy modifier not allowed here. Use call-by-name parameters instead", skipIt = false) in.token match { case v @ (VAL | VAR) => - mods = mods withPosition (in.token.toLong, tokenRange(in)) + mods = mods.withPosition(in.token.toLong, tokenRange(in)) if (v == VAR) mods |= Flags.MUTABLE in.nextToken() case _ => @@ -2632,13 +2632,13 @@ self => syntaxError("lazy not allowed here. Only vals can be lazy", skipIt = false) in.token match { case VAL => - patDefOrDcl(pos, mods withPosition(VAL, tokenRange(in))) + patDefOrDcl(pos, mods.withPosition(VAL, tokenRange(in))) case VAR => - patDefOrDcl(pos, (mods | Flags.MUTABLE) withPosition (VAR, tokenRange(in))) + patDefOrDcl(pos, (mods | Flags.MUTABLE).withPosition(VAR, tokenRange(in))) case DEF => - List(funDefOrDcl(pos, mods withPosition(DEF, tokenRange(in)))) + List(funDefOrDcl(pos, mods.withPosition(DEF, tokenRange(in)))) case TYPE => - List(typeDefOrDcl(pos, mods withPosition(TYPE, tokenRange(in)))) + List(typeDefOrDcl(pos, mods.withPosition(TYPE, tokenRange(in)))) case _ => List(tmplDef(pos, mods)) } @@ -2897,15 +2897,15 @@ self => if (mods.isLazy) syntaxError("classes cannot be lazy", skipIt = false) in.token match { case TRAIT => - classDef(pos, (mods | Flags.TRAIT | Flags.ABSTRACT) withPosition (Flags.TRAIT, tokenRange(in))) + classDef(pos, (mods | Flags.TRAIT | Flags.ABSTRACT).withPosition(Flags.TRAIT, tokenRange(in))) case CLASS => classDef(pos, mods) case CASECLASS => - classDef(pos, (mods | Flags.CASE) withPosition (Flags.CASE, tokenRange(in.prev /*scanner skips on 'case' to 'class', thus take prev*/))) + classDef(pos, (mods | Flags.CASE).withPosition(Flags.CASE, tokenRange(in.prev /*scanner skips on 'case' to 'class', thus take prev*/))) case OBJECT => objectDef(pos, mods) case CASEOBJECT => - objectDef(pos, (mods | Flags.CASE) withPosition (Flags.CASE, tokenRange(in.prev /*scanner skips on 'case' to 'object', thus take prev*/))) + objectDef(pos, (mods | Flags.CASE).withPosition(Flags.CASE, tokenRange(in.prev /*scanner skips on 'case' to 'object', thus take prev*/))) case _ => syntaxErrorOrIncompleteAnd("expected start of definition", skipIt = true)( // assume a class definition so as to have somewhere to stash the annotations diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala index ae4d0d2f1b8e..6c7db1dd5448 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala @@ -147,7 +147,7 @@ trait SymbolTrackers { else { indicatorString + indent + symString(root) + ( if (children.isEmpty) "" - else children map (c => c.indentString(indent + " ")) mkString ("\n", "\n", "") + else children.map(_.indentString(indent + " ")).mkString("\n", "\n", "") ) } } diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index 1ba9390ddc08..8c3f9e28dd3e 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -272,16 +272,10 @@ abstract class Constructors extends Statics with Transform with TypingTransforme closureClass setInfoAndEnter new ClassInfoType(closureParents, newScope, closureClass) - val outerField: TermSymbol = ( - closureClass - newValue(nme.OUTER, impl.pos, PrivateLocal | PARAMACCESSOR) - setInfoAndEnter clazz.tpe - ) - val applyMethod: MethodSymbol = ( - closureClass - newMethod(nme.apply, impl.pos, FINAL) - setInfoAndEnter MethodType(Nil, ObjectTpe) - ) + val outerField: TermSymbol = + closureClass.newValue(nme.OUTER, impl.pos, PrivateLocal | PARAMACCESSOR) setInfoAndEnter clazz.tpe + val applyMethod: MethodSymbol = + closureClass.newMethod(nme.apply, impl.pos, FINAL) setInfoAndEnter MethodType(Nil, ObjectTpe) val outerFieldDef = ValDef(outerField) val closureClassTyper = localTyper.atOwner(closureClass) val applyMethodTyper = closureClassTyper.atOwner(applyMethod) diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 55b8cfbb92ca..e0d2541f4c45 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -138,14 +138,14 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { val resultType = MethodType(List(thisParam), dropNullaryMethod(methodResult)) val selfParamType = singleType(currentOwner.companionModule.thisType, thisParam) - def fixres(tp: Type) = tp substThisAndSym (clazz, selfParamType, clazz.typeParams, tparamsFromClass) - def fixtparam(tp: Type) = tp substSym (clazz.typeParams, tparamsFromClass) + def fixres(tp: Type) = tp.substThisAndSym(clazz, selfParamType, clazz.typeParams, tparamsFromClass) + def fixtparam(tp: Type) = tp.substSym(clazz.typeParams, tparamsFromClass) // We can't substitute symbols on the entire polytype because we // need to modify the bounds of the cloned type parameters, but we // don't want to substitute for the cloned type parameters themselves. val tparams = tparamsFromMethod ::: tparamsFromClass - tparams foreach (_ modifyInfo fixtparam) + tparams.foreach(_ modifyInfo fixtparam) GenPolyType(tparams, fixres(resultType)) // For reference, calling fix on the GenPolyType plays out like this: diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 974f19a4a397..2c6bcd925d78 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -804,7 +804,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { def overrideIn(clazz: Symbol, sym: Symbol) = { val newFlags = (sym.flags | OVERRIDE | SPECIALIZED) & ~(DEFERRED | CASEACCESSOR | PARAMACCESSOR) val sym1 = sym.cloneSymbol(clazz, newFlags) - sym1 modifyInfo (_ asSeenFrom (clazz.tpe, sym1.owner)) + sym1.modifyInfo(_.asSeenFrom(clazz.tpe, sym1.owner)) } val specVal = specializedOverload(sClass, m, env) diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index 88928219dd2d..7e3799da1675 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -174,7 +174,7 @@ abstract class TailCalls extends Transform { val thisParam = method.newSyntheticValueParam(currentClass.typeOfThis) label setInfo MethodType(thisParam :: method.tpe.params, method.tpe_*.finalResultType) if (isEligible) - label substInfo (method.tpe.typeParams, tparams) + label.substInfo(method.tpe.typeParams, tparams) label } diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala index 8c27cd7ce921..843a2ca20e97 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala @@ -517,7 +517,7 @@ trait ScalaLogic extends Interface with Logic with TreeAndTypeAnalysis { def resetUniques() = {_nextId = 0; uniques.clear()} private val uniques = new mutable.HashMap[Tree, Var] - def apply(x: Tree): Var = uniques getOrElseUpdate(x, new Var(x, x.tpe)) + def apply(x: Tree): Var = uniques.getOrElseUpdate(x, new Var(x, x.tpe)) def unapply(v: Var) = Some(v.path) } class Var(val path: Tree, staticTp: Type) extends AbsVar { @@ -575,11 +575,11 @@ trait ScalaLogic extends Interface with Logic with TreeAndTypeAnalysis { // populate equalitySyms // don't care about the result, but want only one fresh symbol per distinct constant c - def registerEquality(c: Const): Unit = {ensureCanModify(); symForEqualsTo getOrElseUpdate(c, Sym(this, c))} + def registerEquality(c: Const): Unit = { ensureCanModify() ; symForEqualsTo.getOrElseUpdate(c, Sym(this, c)) } // return the symbol that represents this variable being equal to the constant `c`, if it exists, otherwise False (for robustness) // (registerEquality(c) must have been called prior, either when constructing the domain or from outside) - def propForEqualsTo(c: Const): Prop = {observed(); symForEqualsTo.getOrElse(c, False)} + def propForEqualsTo(c: Const): Prop = { observed() ; symForEqualsTo.getOrElse(c, False) } // [implementation NOTE: don't access until all potential equalities have been registered using registerEquality]p /** the information needed to construct the boolean proposition that encodes the equality proposition (V = C) @@ -709,8 +709,8 @@ trait ScalaLogic extends Interface with Logic with TreeAndTypeAnalysis { // don't call until all equalities have been registered and registerNull has been called (if needed) def describe = { def domain_s = domain match { - case Some(d) => d mkString (" ::= ", " | ", "// "+ symForEqualsTo.keys) - case _ => symForEqualsTo.keys mkString (" ::= ", " | ", " | ...") + case Some(d) => d.mkString(" ::= ", " | ", "// "+ symForEqualsTo.keys) + case _ => symForEqualsTo.keys.mkString(" ::= ", " | ", " | ...") } s"$this: ${staticTp}${domain_s} // = $path" } diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala index c26fc1138ae1..cf168c5bc2d9 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala @@ -234,14 +234,14 @@ trait MatchApproximation extends TreeAndTypeAnalysis with ScalaLogic with MatchT private[this] val uniqueTypeProps = new mutable.HashMap[(Tree, Type), Eq] def uniqueEqualityProp(testedPath: Tree, rhs: Tree): Prop = - uniqueEqualityProps getOrElseUpdate((testedPath, rhs), Eq(Var(testedPath), ValueConst(rhs))) + uniqueEqualityProps.getOrElseUpdate((testedPath, rhs), Eq(Var(testedPath), ValueConst(rhs))) // overridden in TreeMakersToPropsIgnoreNullChecks def uniqueNonNullProp (testedPath: Tree): Prop = - uniqueNonNullProps getOrElseUpdate(testedPath, Not(Eq(Var(testedPath), NullConst))) + uniqueNonNullProps.getOrElseUpdate(testedPath, Not(Eq(Var(testedPath), NullConst))) def uniqueTypeProp(testedPath: Tree, pt: Type): Prop = - uniqueTypeProps getOrElseUpdate((testedPath, pt), Eq(Var(testedPath), TypeConst(checkableType(pt)))) + uniqueTypeProps.getOrElseUpdate((testedPath, pt), Eq(Var(testedPath), TypeConst(checkableType(pt)))) // a variable in this set should never be replaced by a tree that "does not consist of a selection on a variable in this set" (intuitively) private val pointsToBound = mutable.HashSet(root) @@ -646,7 +646,7 @@ trait MatchAnalysis extends MatchApproximation { def varAssignmentString(varAssignment: Map[Var, (Seq[Const], Seq[Const])]) = varAssignment.toSeq.sortBy(_._1.toString).map { case (v, (trues, falses)) => - val assignment = "== "+ (trues mkString("(", ", ", ")")) +" != ("+ (falses mkString(", ")) +")" + val assignment = "== "+ trues.mkString("(", ", ", ")") +" != ("+ falses.mkString(", ") +")" v +"(="+ v.path +": "+ v.staticTpCheckable +") "+ assignment }.mkString("\n") diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala index b1a9229eea21..6cc5da6cfbf0 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala @@ -294,7 +294,7 @@ trait Interface extends ast.TreeDSL { } new Substitution(newFrom.prependToList(other.from), newTo.prependToList(other.to.mapConserve(apply))) } - override def toString = (from.map(_.name) zip to) mkString("Substitution(", ", ", ")") + override def toString = from.map(_.name).zip(to).mkString("Substitution(", ", ", ")") } object EmptySubstitution extends Substitution(Nil, Nil) { diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 1f7216210080..18a6002a809e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -188,7 +188,7 @@ trait NamesDefaults { self: Analyzer => blockTyper.context.scope enter sym val vd = atPos(sym.pos)(ValDef(sym, qual) setType NoType) // it stays in Vegas: scala/bug#5720, scala/bug#5727 - qual changeOwner (blockTyper.context.owner, sym) + qual.changeOwner(blockTyper.context.owner, sym) val newQual = atPos(qual.pos.focus)(blockTyper.typedQualifier(Ident(sym.name))) val baseFunTransformed = atPos(baseFun.pos.makeTransparent) { diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index cfdc48639999..d875f4530e3e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -434,7 +434,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT if (owner.isClass) validCurrentOwner = true val savedLocalTyper = localTyper localTyper = localTyper.atOwner(tree, if (owner.isModuleNotMethod) owner.moduleClass else owner) - typers = typers updated (owner, localTyper) + typers = typers.updated(owner, localTyper) val result = super.atOwner(tree, owner)(trans) localTyper = savedLocalTyper validCurrentOwner = savedValid diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 930ca4f74acb..28e8e2aca414 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -145,7 +145,7 @@ trait TypeDiagnostics { case _ => Nil } def alternativesString(tree: Tree) = - alternatives(tree) map (x => " " + methodTypeErrorString(x)) mkString ("", " \n", "\n") + alternatives(tree).map(x => " " + methodTypeErrorString(x)).mkString("", " \n", "\n") /** The symbol which the given accessor represents (possibly in part). * This is used for error messages, where we want to speak in terms @@ -278,7 +278,7 @@ trait TypeDiagnostics { val messages = relationships.flatten // the condition verifies no type argument came back None if (messages.size == foundArgs.size) - return messages filterNot (_ == "") mkString ("\n", "\n", "") + return messages.filterNot(_ == "").mkString("\n", "\n", "") } } } @@ -344,13 +344,13 @@ trait TypeDiagnostics { val caseString = if (clazz.isCaseClass && (clazz isSubClass ptSym)) ( clazz.caseFieldAccessors - map (_ => "_") // could use the actual param names here - mkString (s"`case ${clazz.name}(", ",", ")`") + .map(_ => "_") // could use the actual param names here + .mkString(s"`case ${clazz.name}(", ",", ")`") ) else "`case _: " + (clazz.typeParams match { case Nil => "" + clazz.name - case xs => xs map (_ => "_") mkString (clazz.name + "[", ",", "]") + case xs => xs.map(_ => "_").mkString(clazz.name + "[", ",", "]") })+ "`" if (!clazz.exists) "" diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 07d1ffbc757a..48cbabe0cfca 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2775,7 +2775,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // applyOrElse's default parameter: val B1 = methodSym newTypeParameter (newTypeName("B1")) setInfo TypeBounds.empty - val default = methodSym newValueParameter (newTermName("default"), tree.pos.focus, SYNTHETIC) setInfo functionType(List(A1.tpe), B1.tpe) + val default = methodSym.newValueParameter(newTermName("default"), tree.pos.focus, SYNTHETIC) setInfo functionType(List(A1.tpe), B1.tpe) val paramSyms = List(x, default) methodSym setInfo genPolyType(List(A1, B1), MethodType(paramSyms, B1.tpe)) diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index 1024507b8b53..78157272ce83 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -246,7 +246,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => case _ => NoSymbol } trace("wrapping ")(defOwner(expr) -> meth) - val methdef = DefDef(meth, expr changeOwner (defOwner(expr), meth)) + val methdef = DefDef(meth, expr.changeOwner(defOwner(expr), meth)) val moduledef = ModuleDef( obj, diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala index 3ed06f8a7aab..157683206cd5 100644 --- a/src/interactive/scala/tools/nsc/interactive/Global.scala +++ b/src/interactive/scala/tools/nsc/interactive/Global.scala @@ -876,10 +876,10 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") sym.isType || { try { val tp1 = pre.memberType(alt) onTypeError NoType - val tp2 = adaptToNewRunMap(sym.tpe) substSym (originalTypeParams, sym.owner.typeParams) + val tp2 = adaptToNewRunMap(sym.tpe).substSym(originalTypeParams, sym.owner.typeParams) matchesType(tp1, tp2, alwaysMatchSimple = false) || { debugLog(s"findMirrorSymbol matchesType($tp1, $tp2) failed") - val tp3 = adaptToNewRunMap(sym.tpe) substSym (originalTypeParams, alt.owner.typeParams) + val tp3 = adaptToNewRunMap(sym.tpe).substSym(originalTypeParams, alt.owner.typeParams) matchesType(tp1, tp3, alwaysMatchSimple = false) || { debugLog(s"findMirrorSymbol fallback matchesType($tp1, $tp3) failed") false diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 2ee3891b3c8b..578ae7e29017 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -14,14 +14,14 @@ package scala package runtime import scala.collection.{AbstractIterator, AnyConstr, SortedOps, StrictOptimizedIterableOps, StringOps, StringView, View} +import scala.collection.generic.IsIterable import scala.collection.immutable.{ArraySeq, NumericRange} import scala.collection.mutable.StringBuilder +import scala.math.min import scala.reflect.{ClassTag, classTag} import java.lang.{Class => jClass} import java.lang.reflect.{Method => JMethod} -import scala.collection.generic.IsIterable - /** The object ScalaRunTime provides support methods required by * the scala runtime. All these methods should be considered * outside the API and subject to change or removal without notice. @@ -239,7 +239,7 @@ object ScalaRunTime { // Special casing Unit arrays, the value class which uses a reference array type. def arrayToString(x: AnyRef) = { if (x.getClass.getComponentType == classOf[BoxedUnit]) - 0 until (array_length(x) min maxElements) map (_ => "()") mkString ("Array(", ", ", ")") + (0 until min(array_length(x), maxElements)).map(_ => "()").mkString("Array(", ", ", ")") else x.asInstanceOf[Array[_]].iterator.take(maxElements).map(inner).mkString("Array(", ", ", ")") } @@ -254,10 +254,10 @@ object ScalaRunTime { case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x case x if useOwnToString(x) => x.toString case x: AnyRef if isArray(x) => arrayToString(x) - case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.collectionClassName + "(", ", ", ")") - case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.collectionClassName + "(", ", ", ")") + case x: scala.collection.Map[_, _] => x.iterator.take(maxElements).map(mapInner).mkString(x.collectionClassName + "(", ", ", ")") + case x: Iterable[_] => x.iterator.take(maxElements).map(inner).mkString(x.collectionClassName + "(", ", ", ")") case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma - case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") + case x: Product if isTuple(x) => x.productIterator.map(inner).mkString("(", ",", ")") case x => x.toString } diff --git a/src/partest/scala/tools/partest/DirectTest.scala b/src/partest/scala/tools/partest/DirectTest.scala index 138ffaf40c1c..229b2715df84 100644 --- a/src/partest/scala/tools/partest/DirectTest.scala +++ b/src/partest/scala/tools/partest/DirectTest.scala @@ -17,6 +17,7 @@ import scala.tools.cmd.CommandLineParser import scala.tools.nsc._ import scala.tools.nsc.reporters.{ConsoleReporter, Reporter} import scala.tools.nsc.settings.ScalaVersion +import scala.util.chaining._ /** Test with code which is embedded as a string. * @@ -46,13 +47,11 @@ abstract class DirectTest { // a default Settings object using only extraSettings def settings: Settings = newSettings(CommandLineParser.tokenize(extraSettings)) // settings factory using given args and also debug settings - def newSettings(args: List[String]) = { - val s = new Settings + def newSettings(args: List[String]) = (new Settings).tap { s => val allArgs = args ++ CommandLineParser.tokenize(debugSettings) - log("newSettings: allArgs = " + allArgs) + log(s"newSettings: allArgs = $allArgs") val (success, residual) = s.processArguments(allArgs, processAll = false) assert(success && residual.isEmpty, s"Bad settings [${args.mkString(",")}], residual [${residual.mkString(",")}]") - s } // new compiler using given ad hoc args, -d and extraSettings def newCompiler(args: String*): Global = { diff --git a/src/partest/scala/tools/partest/nest/Runner.scala b/src/partest/scala/tools/partest/nest/Runner.scala index 12dd7f6b3016..eef606d3db32 100644 --- a/src/partest/scala/tools/partest/nest/Runner.scala +++ b/src/partest/scala/tools/partest/nest/Runner.scala @@ -369,7 +369,7 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { // Apply judiciously; there are line comments in the "stub implementations" error output. val slashes = """[/\\]+""".r - def squashSlashes(s: String) = slashes replaceAllIn (s, "/") + def squashSlashes(s: String) = slashes.replaceAllIn(s, "/") // this string identifies a path and is also snipped from log output. val elided = parentFile.getAbsolutePath @@ -379,14 +379,12 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { // no spaces in test file paths below root, because otherwise how to detect end of path string? val pathFinder = raw"""(?i)\Q${elided}${File.separator}\E([\${File.separator}\S]*)""".r - def canonicalize(s: String): String = ( - pathFinder replaceAllIn (s, m => - Regex.quoteReplacement(ellipsis + squashSlashes(m group 1))) - ) + def canonicalize(s: String): String = + pathFinder.replaceAllIn(s, m => Regex.quoteReplacement(ellipsis + squashSlashes(m group 1))) def masters = { val files = List(new File(parentFile, "filters"), new File(suiteRunner.pathSettings.srcDir.path, "filters")) - files filter (_.exists) flatMap (_.fileLines) map (_.trim) filter (s => !(s startsWith "#")) + files.filter(_.exists).flatMap(_.fileLines).map(_.trim).filter(s => !(s startsWith "#")) } val filters = toolArgs("filter", split = false) ++ masters val elisions = ListBuffer[String]() @@ -403,7 +401,7 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { if (suiteRunner.verbose && elisions.nonEmpty) { import suiteRunner.log._ val emdash = bold(yellow("--")) - pushTranscript(s"filtering ${logFile.getName}$EOL${elisions mkString (emdash, EOL + emdash, EOL)}") + pushTranscript(s"filtering ${logFile.getName}$EOL${elisions.mkString(emdash, EOL + emdash, EOL)}") } } diff --git a/src/partest/scala/tools/partest/package.scala b/src/partest/scala/tools/partest/package.scala index 4a53355a2078..45205a93f1f7 100644 --- a/src/partest/scala/tools/partest/package.scala +++ b/src/partest/scala/tools/partest/package.scala @@ -115,10 +115,9 @@ package object partest { } implicit class ExecutorOps(val executor: ExecutorService) { - def awaitTermination[A](wait: Duration)(failing: => A = ()): Option[A] = ( - if (executor awaitTermination (wait.length, wait.unit)) None + def awaitTermination[A](wait: Duration)(failing: => A = ()): Option[A] = + if (executor.awaitTermination(wait.length, wait.unit)) None else Some(failing) - ) } implicit def temporaryPath2File(x: Path): File = x.jfile diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala index 40f90f133b67..ba89438fb650 100644 --- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala +++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala @@ -146,7 +146,7 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable => private[scala] def completeAnnotationToString(annInfo: AnnotationInfo) = { import annInfo._ val s_args = if (!args.isEmpty) args.mkString("(", ", ", ")") else "" - val s_assocs = if (!assocs.isEmpty) (assocs map { case (x, y) => s"$x = $y" } mkString ("(", ", ", ")")) else "" + val s_assocs = if (!assocs.isEmpty) assocs.map { case (x, y) => s"$x = $y" }.mkString("(", ", ", ")") else "" s"${atp}${s_args}${s_assocs}" } diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index e3ce59e7cd8b..c7e78e0f6d27 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -1203,7 +1203,7 @@ trait Definitions extends api.StandardDefinitions { normalizedParents(parents) mkString " with " def valueParamsString(tp: Type) = tp match { - case MethodType(params, _) => params map (_.defString) mkString ("(", ", ", ")") + case MethodType(params, _) => params.map(_.defString).mkString("(", ", ", ")") case _ => "" } diff --git a/src/reflect/scala/reflect/internal/Kinds.scala b/src/reflect/scala/reflect/internal/Kinds.scala index 81d07d972199..51bcf98ec74f 100644 --- a/src/reflect/scala/reflect/internal/Kinds.scala +++ b/src/reflect/scala/reflect/internal/Kinds.scala @@ -77,7 +77,7 @@ trait Kinds { private def buildMessage(xs: List[SymPair], f: (Symbol, Symbol) => String) = ( if (xs.isEmpty) "" - else xs map f.tupled mkString ("\n", ", ", "") + else xs.map(f.tupled).mkString("\n", ", ", "") ) def errorMessage(targ: Type, tparam: Symbol): String = ( diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala index 56c6ec8a2e82..e7d434ca3a95 100644 --- a/src/reflect/scala/reflect/internal/Mirrors.scala +++ b/src/reflect/scala/reflect/internal/Mirrors.scala @@ -51,7 +51,7 @@ trait Mirrors extends api.Mirrors { getModuleOrClass(path.toString, len, path.newName(_)) private def getModuleOrClass(path: String, len: Int, toName: String => Name): Symbol = { - val point = path lastIndexOf ('.', len - 1) + val point = path.lastIndexOf('.', len - 1) val owner = if (point > 0) getModuleOrClass(path, point, newTermName(_)) else RootClass diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 29d648439332..2cedfc5478be 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -1819,9 +1819,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => } val oldsyms = oldsymbuf.toList val newsyms = newsymbuf.toList - for (sym <- newsyms) { - addMember(thistp, tp, sym modifyInfo (_ substThisAndSym(this, thistp, oldsyms, newsyms))) - } + for (sym <- newsyms) + addMember(thistp, tp, sym.modifyInfo(_.substThisAndSym(this, thistp, oldsyms, newsyms))) } tp } diff --git a/src/reflect/scala/reflect/internal/TypeDebugging.scala b/src/reflect/scala/reflect/internal/TypeDebugging.scala index ebb8c16b4f5b..4a73da558b67 100644 --- a/src/reflect/scala/reflect/internal/TypeDebugging.scala +++ b/src/reflect/scala/reflect/internal/TypeDebugging.scala @@ -85,7 +85,7 @@ trait TypeDebugging { // otherwise case classes are caught looking like products case _: Tree | _: Type => "" + x case x: IterableOnce[_] => x.iterator mkString ", " - case x: Product => x.productIterator mkString ("(", ", ", ")") + case x: Product => x.productIterator.mkString("(", ", ", ")") case _ => "" + x } def ptBlock(label: String, pairs: (String, Any)*): String = { @@ -129,7 +129,7 @@ trait TypeDebugging { def parentheses(xs: List[_]): String = xs.mkString("(", ", ", ")") def params(params: List[Symbol]): String = { val paramsStrPre = if (params.nonEmpty && params.head.isImplicit) "(implicit " else "(" - params map (_.defStringWithoutImplicit) mkString (paramsStrPre, ", ", ")") + params.map(_.defStringWithoutImplicit).mkString(paramsStrPre, ", ", ")") } def brackets(xs: List[_]): String = if (xs.isEmpty) "" else xs.mkString("[", ", ", "]") def tparams(tparams: List[Type]): String = brackets(tparams map debug) diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 47d08b8de35a..df504a1b6266 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -1567,8 +1567,8 @@ trait Types */ private[internal] def starNotation(typeString: Type => String): String = { if (emptyLowerBound && emptyUpperBound) "" - else if (emptyLowerBound) "(" + typeString(hi) + ")" - else "(%s, %s)" format (typeString(lo), typeString(hi)) + else if (emptyLowerBound) s"(${typeString(hi)})" + else s"(${typeString(lo)}, ${typeString(hi)})" } override def kind = "TypeBoundsType" override def mapOver(map: TypeMap): Type = { @@ -2640,7 +2640,7 @@ trait Types private def refinementDecls = fullyInitializeScope(decls) filter (sym => sym.isPossibleInRefinement && sym.isPublic) private def refinementString = ( if (sym.isStructuralRefinement) - refinementDecls map (_.defString) mkString("{", "; ", "}") + refinementDecls.map(_.defString).mkString("{", "; ", "}") else "" ) protected def finishPrefix(rest: String) = ( @@ -3146,7 +3146,7 @@ trait Types } private def existentialClauses = { - val str = quantified map (_.existentialToString) mkString (" forSome { ", "; ", " }") + val str = quantified.map(_.existentialToString).mkString(" forSome { ", "; ", " }") if (settings.explaintypes) "(" + str + ")" else str } @@ -3747,7 +3747,7 @@ trait Types private def tparamsOfSym(sym: Symbol) = sym.info match { case PolyType(tparams, _) if !tparams.isEmpty => - tparams map (_.defString) mkString("[", ",", "]") + tparams.map(_.defString).mkString("[", ",", "]") case _ => "" } def originName = origin.typeSymbolDirect.decodedName @@ -4426,7 +4426,7 @@ trait Types case _: ConstantType => tp // Java enum constants: don't widen to the enum type! case _ => tp.widen // C.X.type widens to C.this.X.type, otherwise `tp asSeenFrom (pre, C)` has no effect. } - val memType = widened asSeenFrom (pre, tp.typeSymbol.owner) + val memType = widened.asSeenFrom(pre, tp.typeSymbol.owner) if (tp eq widened) memType else memType.narrow } else loop(tp.prefix) memberType tp.typeSymbol diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala index e6d3496e4662..977dc10f4268 100644 --- a/src/reflect/scala/reflect/internal/transform/Erasure.scala +++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala @@ -144,7 +144,7 @@ trait Erasure { else if (sym.isRefinementClass) apply(mergeParents(tp.parents)) else if (sym.isDerivedValueClass) eraseDerivedValueClassRef(tref) else if (sym.isClass) eraseNormalClassRef(tref) - else apply(sym.info asSeenFrom (pre, sym.owner)) // alias type or abstract type + else apply(sym.info.asSeenFrom(pre, sym.owner)) // alias type or abstract type case PolyType(tparams, restpe) => apply(restpe) case ExistentialType(tparams, restpe) => diff --git a/src/reflect/scala/reflect/internal/util/Position.scala b/src/reflect/scala/reflect/internal/util/Position.scala index 85dc54bd1651..db2d30df0a35 100644 --- a/src/reflect/scala/reflect/internal/util/Position.scala +++ b/src/reflect/scala/reflect/internal/util/Position.scala @@ -152,7 +152,7 @@ private[util] trait InternalPositionImpl { * |^ means union, taking the point of the rhs * ^| means union, taking the point of the lhs */ - def |(that: Position, poses: Position*): Position = poses.foldLeft(this | that)(_ | _) + //def |(that: Position, poses: Position*): Position = poses.foldLeft(this | that)(_ | _) def |(that: Position): Position = this union that def ^(point: Int): Position = this withPoint point def |^(that: Position): Position = (this | that) ^ that.point diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 7b1bfab2d2c6..f68959a2382e 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -693,7 +693,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive val tparam = sOwner(jtvar).newTypeParameter(newTypeName(jtvar.getName)) .setInfo(new TypeParamCompleter(jtvar)) markFlagsCompleted(tparam)(mask = AllFlags) - tparamCache enter (jtvar, tparam) + tparamCache.enter(jtvar, tparam) tparam } @@ -1206,7 +1206,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive private def jmethodAsScala1(jmeth: jMethod): MethodSymbol = { val clazz = sOwner(jmeth) val meth = clazz.newMethod(newTermName(jmeth.getName), NoPosition, jmeth.scalaFlags) - methodCache enter (jmeth, meth) + methodCache.enter(jmeth, meth) val tparams = jmeth.getTypeParameters.toList map createTypeParameter val params = jparamsAsScala(meth, jmeth.getParameters.toList) val resulttpe = typeToScala(jmeth.getGenericReturnType) @@ -1232,7 +1232,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive // [Martin] Note: I know there's a lot of duplication wrt jmethodAsScala, but don't think it's worth it to factor this out. val clazz = sOwner(jconstr) val constr = clazz.newConstructor(NoPosition, jconstr.scalaFlags) - constructorCache enter (jconstr, constr) + constructorCache.enter(jconstr, constr) val tparams = jconstr.getTypeParameters.toList map createTypeParameter val params = jparamsAsScala(constr, jconstr.getParameters.toList) setMethType(constr, tparams, params, clazz.tpe) @@ -1337,10 +1337,10 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive val jclazz = classToJava(meth.owner.asClass) val paramClasses = transformedType(meth).paramTypes map typeToJavaClass val jname = meth.name.dropLocal.toString - try jclazz getDeclaredMethod (jname, paramClasses: _*) + try jclazz.getDeclaredMethod(jname, paramClasses: _*) catch { case ex: NoSuchMethodException => - jclazz getDeclaredMethod (expandedName(meth), paramClasses: _*) + jclazz.getDeclaredMethod(expandedName(meth), paramClasses: _*) } } diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/JavapClass.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/JavapClass.scala index 34a76e721c41..4b96dd731d6c 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/JavapClass.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/JavapClass.scala @@ -491,11 +491,11 @@ class JavapTask(val loader: ScalaClassLoader, intp: Repl) extends JavapTool { // DisassemblerTool.getStandardFileManager(reporter,locale,charset) val defaultFileManager: JavaFileManager = - (loader.tryToLoadClass[JavaFileManager]("com.sun.tools.javap.JavapFileManager").get getMethod ( + (loader.tryToLoadClass[JavaFileManager]("com.sun.tools.javap.JavapFileManager").get.getMethod( "create", classOf[DiagnosticListener[_]], classOf[PrintWriter] - ) invoke (null, reporter, new PrintWriter(System.err, true))).asInstanceOf[JavaFileManager] + ).invoke(null, reporter, new PrintWriter(System.err, true))).asInstanceOf[JavaFileManager] // manages named arrays of bytes, which might have failed to load class JavapFileManager(val managed: Seq[Input])(delegate: JavaFileManager = defaultFileManager) diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Scripted.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Scripted.scala index b1348adb38da..5587c8333c9c 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Scripted.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Scripted.scala @@ -214,7 +214,7 @@ class Scripted(@BeanProperty val factory: ScriptEngineFactory, settings: Setting override def eval(context: ScriptContext) = withScriptContext(context) { if (!first) - intp.addBackReferences(req) fold ( + intp.addBackReferences(req).fold( { line => Scripted.this.eval(line); null }, // we're evaluating after recording the request instead of other way around, but that should be ok, right? evalAndRecord(context, _)) else try evalAndRecord(context, req) finally first = false diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala index 03fb786ae8b4..212084a4f88b 100644 --- a/src/repl/scala/tools/nsc/interpreter/IMain.scala +++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala @@ -1324,7 +1324,7 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade val termMsg = if (terms.isEmpty) "" else s"${terms.size} terms" val implicitMsg = if (imps.isEmpty) "" else s"${imps.size} are implicit" val foundMsg = if (found.isEmpty) "" else found.mkString(" // imports: ", ", ", "") - val statsMsg = List(typeMsg, termMsg, implicitMsg) filterNot (_ == "") mkString ("(", ", ", ")") + val statsMsg = List(typeMsg, termMsg, implicitMsg).filterNot(_ == "").mkString("(", ", ", ")") f"${idx + 1}%2d) ${handler.importString}%-30s $statsMsg$foundMsg" } diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala index dfbbb0d9af78..04a83d795213 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala @@ -209,7 +209,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { case d: MemberEntity with Def => val paramLists: List[String] = if (d.valueParams.isEmpty) Nil - else d.valueParams map (ps => ps map (_.resultType.name) mkString ("(",",",")")) + else d.valueParams.map(ps => ps.map(_.resultType.name).mkString("(",",",")")) paramLists.mkString case _ => "" } diff --git a/test/benchmarks/src/main/scala/scala/collection/immutable/HashMapBulkBenchmark.scala b/test/benchmarks/src/main/scala/scala/collection/immutable/HashMapBulkBenchmark.scala index 9411681ad96a..9c653f359046 100644 --- a/test/benchmarks/src/main/scala/scala/collection/immutable/HashMapBulkBenchmark.scala +++ b/test/benchmarks/src/main/scala/scala/collection/immutable/HashMapBulkBenchmark.scala @@ -187,7 +187,7 @@ abstract class HashMapBaseBulkBenchmark { def base (i:Int) = { baseData(if (i < 0) baseData.length+i else i) } - shared(0) = (-10 to (0, 1)).foldLeft (base(-10)) {case (a, b) => a ++ base(b)} + shared(0) = (-10.to(0, 1)).foldLeft(base(-10)) { case (a, b) => a ++ base(b) } for (i <- 1 until baseData.length - 10) { shared(i) = shared(i - 1) -- base(i - 10).keys ++ base(i) } diff --git a/test/benchmarks/src/main/scala/scala/collection/immutable/MapAppendBenchmark.scala b/test/benchmarks/src/main/scala/scala/collection/immutable/MapAppendBenchmark.scala index a6aaf1a664a1..f7669233646a 100644 --- a/test/benchmarks/src/main/scala/scala/collection/immutable/MapAppendBenchmark.scala +++ b/test/benchmarks/src/main/scala/scala/collection/immutable/MapAppendBenchmark.scala @@ -43,7 +43,7 @@ class MapAppendBenchmark { var m = Map.empty[Int, Unit] var i = 0 while(i < size) { - m = m + ((i -> ()), ((i+size) -> ())) + m = m.+((i -> ()), ((i+size) -> ())) i += 1 } bh.consume(m) @@ -54,7 +54,7 @@ class MapAppendBenchmark { var m = Map.empty[Int, Unit] var i = 0 while(i < size) { - m = m + ((i -> ()), ((i+size) -> ()), empty: _*) + m = m.+((i -> ()), ((i+size) -> ()), empty: _*) i += 1 } bh.consume(m) diff --git a/test/junit/scala/collection/IteratorTest.scala b/test/junit/scala/collection/IteratorTest.scala index 23ce1a97b24e..4f9c9cef57af 100644 --- a/test/junit/scala/collection/IteratorTest.scala +++ b/test/junit/scala/collection/IteratorTest.scala @@ -12,6 +12,8 @@ import Seq.empty @RunWith(classOf[JUnit4]) class IteratorTest { + private def from0 = Iterator.from(0) + @Test def groupedIteratorShouldNotAskForUnneededElement(): Unit = { var counter = 0 val it = new Iterator[Int] { var i = 0 ; def hasNext = { counter = i; true } ; def next() = { i += 1; i } } @@ -48,16 +50,16 @@ class IteratorTest { } @Test def sliceIsChainable(): Unit = { - assertSameElements(3 to 6, Iterator from 0 slice (3, 7)) - assertSameElements(empty, Iterator from 0 slice (3, 3)) - assertSameElements(0 to 2, Iterator from 0 slice (-1, 3)) - assertSameElements(empty, Iterator from 0 slice (3, -1)) - assertSameElements(6 to 12 by 2, Iterator from 0 slice (3, 7) map (2 * _)) - assertSameElements(6 to 12 by 2, Iterator from 0 map (2 * _) slice (3, 7)) - assertSameElements(4 to 6, Iterator from 0 slice (3, 7) drop 1) - assertSameElements(4 to 7, Iterator from 0 drop 1 slice (3, 7)) - assertSameElements(4 to 5, Iterator from 0 slice (3, 7) slice (1, 3)) - assertSameElements(4 to 6, Iterator from 0 slice (3, 7) slice (1, 10)) + assertSameElements(3 to 6, from0.slice(3, 7)) + assertSameElements(empty, from0.slice(3, 3)) + assertSameElements(0 to 2, from0.slice(-1, 3)) + assertSameElements(empty, from0.slice(3, -1)) + assertSameElements(6 to 12 by 2, from0.slice(3, 7).map(2 * _)) + assertSameElements(6 to 12 by 2, from0.map(2 * _).slice(3, 7)) + assertSameElements(4 to 6, from0.slice(3, 7).drop(1)) + assertSameElements(4 to 7, from0.drop(1).slice(3, 7)) + assertSameElements(4 to 5, from0.slice(3, 7).slice(1, 3)) + assertSameElements(4 to 6, from0.slice(3, 7).slice(1, 10)) } // test/files/run/iterator-concat.scala diff --git a/test/junit/scala/collection/SetMapConsistencyTest.scala b/test/junit/scala/collection/SetMapConsistencyTest.scala index afd80aabf804..5718d1acfb63 100644 --- a/test/junit/scala/collection/SetMapConsistencyTest.scala +++ b/test/junit/scala/collection/SetMapConsistencyTest.scala @@ -396,7 +396,7 @@ class SetMapConsistencyTest { assert { val lm2 = new LongMap[String](_.toString) - lm2 += (5L -> "fish", 0L -> "unicorn") + lm2.+=(5L -> "fish", 0L -> "unicorn") val hm2 = (new HashMap[Long,String]) ++= lm2 List(Long.MinValue, 0L, 1L, 5L).forall(i => lm2.get(i) == hm2.get(i) && @@ -443,7 +443,7 @@ class SetMapConsistencyTest { assert { val arm2 = new AnyRefMap[String, String](x => if (x==null) "null" else x) - arm2 += ("cod" -> "fish", "Rarity" -> "unicorn") + arm2.+=("cod" -> "fish", "Rarity" -> "unicorn") val hm2 = (new HashMap[String,String]) ++= arm2 List(null, "cod", "sparrow", "Rarity").forall { i => //println((arm2.get(i), hm2.get(i))) @@ -519,10 +519,10 @@ class SetMapConsistencyTest { @Test def testSI8815(): Unit = { val lm = new scala.collection.mutable.LongMap[String] - lm += (Long.MinValue, "min") - lm += (-1, "neg-one") - lm += (0, "zero") - lm += (Long.MaxValue, "max") + lm.+=(Long.MinValue, "min") + lm.+=(-1, "neg-one") + lm.+=(0, "zero") + lm.+=(Long.MaxValue, "max") var nit = 0 lm.iterator.foreach(_ => nit += 1) var nfe = 0 diff --git a/test/junit/scala/collection/immutable/IndexedSeqTest.scala b/test/junit/scala/collection/immutable/IndexedSeqTest.scala index 65284eb98d79..fe98c997c7ef 100644 --- a/test/junit/scala/collection/immutable/IndexedSeqTest.scala +++ b/test/junit/scala/collection/immutable/IndexedSeqTest.scala @@ -4,7 +4,6 @@ import org.junit._ import Assert._ import scala.collection.Seq.empty -import scala.language.postfixOps import scala.tools.testkit.AssertUtil._ import scala.tools.testkit.AllocationTest @@ -99,43 +98,42 @@ class IndexedSeqTest extends AllocationTest { @Test def testforwardSliceEquals(): Unit = { - def generateTestIter = (0 to 10).view iterator - - - assertSameElements(empty toList, generateTestIter slice (3, -1)) - assertSameElements(empty toList, generateTestIter slice (0, 0)) - assertSameElements(empty, generateTestIter slice (3, 3)) - assertSameElements(List(0) , generateTestIter slice (0, 1)) - assertSameElements(0 to 1 , generateTestIter slice (0, 2)) - assertSameElements(3 to 6 toList, generateTestIter slice(3,7)) - assertSameElements(0 to 2 toList, generateTestIter slice (-1, 3)) - assertSameElements(0 to 10 toList, generateTestIter slice (0, 11)) - assertSameElements(6 to 12 by 2 toList, generateTestIter slice (3, 7) map (2 * _)) - assertSameElements(6 to 12 by 2 toList, generateTestIter map (2 * _) slice (3, 7)) - assertSameElements(4 to 6 toList, generateTestIter slice (3, 7) drop 1) - assertSameElements(4 to 7 toList, generateTestIter drop 1 slice (3, 7)) - assertSameElements(4 to 5 toList, generateTestIter slice (3, 7) slice (1, 3)) - assertSameElements(4 to 6 toList, generateTestIter slice (3, 7) slice (1, 10)) + def generateTestIter = (0 to 10).view.iterator + + assertSameElements(empty.toList, generateTestIter.slice(3, -1)) + assertSameElements(empty.toList, generateTestIter.slice(0, 0)) + assertSameElements(empty, generateTestIter.slice(3, 3)) + assertSameElements(List(0), generateTestIter.slice(0, 1)) + assertSameElements(0 to 1, generateTestIter.slice(0, 2)) + assertSameElements((3 to 6).toList, generateTestIter.slice(3,7)) + assertSameElements((0 to 2).toList, generateTestIter.slice(-1, 3)) + assertSameElements((0 to 10).toList, generateTestIter.slice(0, 11)) + assertSameElements((6 to 12 by 2).toList, generateTestIter.slice(3, 7).map(2 * _)) + assertSameElements((6 to 12 by 2).toList, generateTestIter.map(2 * _).slice(3, 7)) + assertSameElements((4 to 6).toList, generateTestIter.slice(3, 7).drop(1)) + assertSameElements((4 to 7).toList, generateTestIter.drop(1).slice(3, 7)) + assertSameElements((4 to 5).toList, generateTestIter.slice(3, 7).slice(1, 3)) + assertSameElements((4 to 6).toList, generateTestIter.slice(3, 7).slice(1, 10)) } @Test def testbackwardSliceEquals(): Unit = { - def generateTestIter = (0 to 10).view reverseIterator - - assertSameElements(empty toList, generateTestIter slice (3, -1)) - assertSameElements(empty toList, generateTestIter slice (3, 2)) - assertSameElements(empty, generateTestIter slice (0, 0)) - assertSameElements(empty, generateTestIter slice (3, 3)) - assertSameElements(List(10) , generateTestIter slice (0, 1)) - assertSameElements(10 to 9 by -1 , generateTestIter slice (0, 2)) - assertSameElements(7 to 4 by -1 toList, generateTestIter slice(3,7)) - assertSameElements(10 to 8 by -1 toList, generateTestIter slice (-1, 3)) - assertSameElements(14 to 8 by -2 toList, generateTestIter slice (3, 7) map (2 * _)) - assertSameElements(14 to 8 by -2 toList, generateTestIter map (2 * _) slice (3, 7)) - assertSameElements(6 to 4 by -1 toList, generateTestIter slice (3, 7) drop 1) - assertSameElements(6 to 3 by -1 toList, generateTestIter drop 1 slice (3, 7)) - assertSameElements(6 to 5 by -1 toList, generateTestIter slice (3, 7) slice (1, 3)) - assertSameElements(6 to 4 by -1 toList, generateTestIter slice (3, 7) slice (1, 10)) + def generateTestIter = (0 to 10).view.reverseIterator + + assertSameElements(empty.toList, generateTestIter.slice(3, -1)) + assertSameElements(empty.toList, generateTestIter.slice(3, 2)) + assertSameElements(empty, generateTestIter.slice(0, 0)) + assertSameElements(empty, generateTestIter.slice(3, 3)) + assertSameElements(List(10), generateTestIter.slice(0, 1)) + assertSameElements(10 to 9 by -1, generateTestIter.slice(0, 2)) + assertSameElements((7 to 4 by -1).toList, generateTestIter.slice(3,7)) + assertSameElements((10 to 8 by -1).toList, generateTestIter.slice(-1, 3)) + assertSameElements((14 to 8 by -2).toList, generateTestIter.slice(3, 7).map(2 * _)) + assertSameElements((14 to 8 by -2).toList, generateTestIter.map(2 * _).slice(3, 7)) + assertSameElements((6 to 4 by -1).toList, generateTestIter.slice(3, 7).drop(1)) + assertSameElements((6 to 3 by -1).toList, generateTestIter.drop(1).slice(3, 7)) + assertSameElements((6 to 5 by -1).toList, generateTestIter.slice(3, 7).slice(1, 3)) + assertSameElements((6 to 4 by -1).toList, generateTestIter.slice(3, 7).slice(1, 10)) } } diff --git a/test/junit/scala/collection/mutable/ArrayDequeTest.scala b/test/junit/scala/collection/mutable/ArrayDequeTest.scala index 9fc5b07ee149..c5e353ddb1ca 100644 --- a/test/junit/scala/collection/mutable/ArrayDequeTest.scala +++ b/test/junit/scala/collection/mutable/ArrayDequeTest.scala @@ -21,7 +21,7 @@ class ArrayDequeTest { assertEquals(buffer.reverse, buffer2.reverse) } - apply(_ += (1, 2, 3, 4, 5)) + apply(_.+=(1, 2, 3, 4, 5)) apply(_.prepend(6).prepend(7).prepend(8)) apply(_.trimStart(2)) apply(_.trimEnd(3)) diff --git a/test/junit/scala/collection/mutable/CollisionProofHashMapTest.scala b/test/junit/scala/collection/mutable/CollisionProofHashMapTest.scala index 8089d61ae2a9..135f9ebbef6b 100644 --- a/test/junit/scala/collection/mutable/CollisionProofHashMapTest.scala +++ b/test/junit/scala/collection/mutable/CollisionProofHashMapTest.scala @@ -125,7 +125,7 @@ class CollisionProofHashMapTest { assertEquals(m7(3), "c") // deprecated - val m8 = (m1 + (4 -> "d", 5 -> "e")).addOne(3 -> "c") + val m8 = m1.+(4 -> "d", 5 -> "e").addOne(3 -> "c") assertEquals(m8(3), "c") // deprecated diff --git a/test/junit/scala/io/SourceTest.scala b/test/junit/scala/io/SourceTest.scala index a0f46ee4deb4..cebabcfabe80 100644 --- a/test/junit/scala/io/SourceTest.scala +++ b/test/junit/scala/io/SourceTest.scala @@ -76,7 +76,7 @@ class SourceTest { override def pos = _pos private[this] var _ch: Char = _ override def ch = _ch - override def next = { + override def next() = { _ch = iter.next() _pos += 1 _ch diff --git a/test/scalacheck/range.scala b/test/scalacheck/range.scala index d3d5f794195e..3344d3be6315 100644 --- a/test/scalacheck/range.scala +++ b/test/scalacheck/range.scala @@ -10,15 +10,15 @@ class Counter(r: Range) { def apply(x: Int) = { cnt += 1L if (cnt % 500000000L == 0L) { - println("Working: %s %d %d" format (str, cnt, x)) + println(f"Working: $str $cnt%d $x%d") } if (cnt > (Int.MaxValue.toLong + 1) * 2) { - val msg = "Count exceeds maximum possible for an Int Range: %s" format str + val msg = s"Count exceeds maximum possible for an Int Range: $str" println(msg) // exception is likely to be eaten by an out of memory error sys error msg } if ((r.step > 0 && last.exists(_ > x)) || (r.step < 0 && last.exists(_ < x))) { - val msg = "Range %s wrapped: %d %s" format (str, x, last.toString) + val msg = f"Range $str wrapped: $x%d ${last.toString}" println(msg) // exception is likely to be eaten by an out of memory error sys error msg } From 25bbbf4f987c7d6b16529102e6997ce5e0c38b1a Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Mon, 4 May 2020 15:08:56 -0700 Subject: [PATCH 3/6] Don't warn about implicit multiargs For example, `def ?[A: T: U]` may be intended to be invoked `r ?` and not `r ? (t, u)`. --- src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 5 ++--- test/files/neg/sd503.check | 9 ++++++--- test/files/neg/sd503.scala | 7 +++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index a04bb85bdb5d..5bccb78be012 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2355,13 +2355,12 @@ self => warning(in.offset, s"$ttl parameter sections are effectively implicit", WarningCategory.WFlagExtraImplicit) } val result = vds.toList - if (owner == nme.CONSTRUCTOR && (result.isEmpty || (result.head take 1 exists (_.mods.isImplicit)))) { + if (owner == nme.CONSTRUCTOR && (result.isEmpty || result.head.take(1).exists(_.mods.isImplicit))) in.token match { case LBRACKET => syntaxError(in.offset, "no type parameters allowed here", skipIt = false) case EOF => incompleteInputError("auxiliary constructor needs non-implicit parameter list") case _ => syntaxError(start, "auxiliary constructor needs non-implicit parameter list", skipIt = false) } - } addEvidenceParams(owner, result, contextBounds) } @@ -2801,7 +2800,7 @@ self => } if (settings.multiargInfix) vparamss match { - case (_ :: _ :: _) :: Nil if settings.multiargInfix && Chars.isOperatorPart(name.decoded.last) => + case (h :: _ :: _) :: Nil if !h.mods.hasFlag(Flags.IMPLICIT) && Chars.isOperatorPart(name.decoded.last) => warning(nameOffset, "multiarg infix syntax looks like a tuple and will be deprecated", WarningCategory.LintMultiargInfix) case _ => } diff --git a/test/files/neg/sd503.check b/test/files/neg/sd503.check index 99c909ce3c7d..056e0864f27c 100644 --- a/test/files/neg/sd503.check +++ b/test/files/neg/sd503.check @@ -16,7 +16,10 @@ sd503.scala:29: warning: multiarg infix syntax looks like a tuple and will be de sd503.scala:34: warning: multiarg infix syntax looks like a tuple and will be deprecated def x_=(i: Int, j: Int = 1): Unit = devalue = i + j // multiarg, warn ^ -sd503.scala:47: warning: multiarg infix syntax looks like a tuple and will be deprecated +sd503.scala:46: warning: multiarg infix syntax looks like a tuple and will be deprecated + def ++(i: Int, j: Int): Int = i + j // nowarn! (TODO) + ^ +sd503.scala:54: warning: multiarg infix syntax looks like a tuple and will be deprecated def +=(x: A, y: A, zs: A*): this.type = addAll(x +: y +: zs) // very multiarg, warn ^ sd503.scala:13: warning: multiarg infix syntax looks like a tuple and will be deprecated @@ -28,8 +31,8 @@ sd503.scala:15: warning: multiarg infix syntax looks like a tuple and will be de sd503.scala:19: warning: multiarg infix syntax looks like a tuple and will be deprecated def f5() = c x_= (42, 27) // multiarg, warn ^ -sd503.scala:52: warning: multiarg infix syntax looks like a tuple and will be deprecated +sd503.scala:59: warning: multiarg infix syntax looks like a tuple and will be deprecated def f[A](as: Embiggen[A], x: A, y: A, z: A): as.type = as += (x, y, z) // very multiarg, warn ^ -8 warnings +9 warnings 2 errors diff --git a/test/files/neg/sd503.scala b/test/files/neg/sd503.scala index 21a41e70f42a..79caea52d8cc 100644 --- a/test/files/neg/sd503.scala +++ b/test/files/neg/sd503.scala @@ -39,6 +39,13 @@ class D { trait OK { def f(p: (Int, Int)) = p == (42, 17) // nowarn! def g(ps: Embiggen[(Int, Int)]) = ps :+ (42, 17) // nowarn! + + def ?[A: List: reflect.ClassTag] = ??? // nowarn! + + def calculate(): Int = { + def ++(i: Int, j: Int): Int = i + j // nowarn! (TODO) + ++ (42, 17) + } } // Growable is the paradigmatic example From 54f5e7582b74f14534d47c632c11002891430b97 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Mon, 4 May 2020 16:35:42 -0700 Subject: [PATCH 4/6] Infix ops are not local defs Move the check to typer for owner test. --- .../scala/tools/nsc/ast/parser/Parsers.scala | 8 +----- .../scala/tools/nsc/typechecker/Typers.scala | 27 +++++++++++-------- test/files/neg/sd503.check | 23 +++++++--------- test/files/neg/sd503.scala | 2 +- 4 files changed, 28 insertions(+), 32 deletions(-) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 5bccb78be012..7f19e3c6c863 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -18,7 +18,7 @@ package ast.parser import scala.annotation.tailrec import scala.collection.mutable, mutable.ListBuffer -import scala.reflect.internal.{Chars, ModifierFlags => Flags, Precedence} +import scala.reflect.internal.{ModifierFlags => Flags, Precedence} import scala.reflect.internal.util.{FreshNameCreator, ListOfNil, Position, SourceFile} import Tokens._ import scala.tools.nsc.Reporting.WarningCategory @@ -2798,12 +2798,6 @@ self => } expr() } - if (settings.multiargInfix) - vparamss match { - case (h :: _ :: _) :: Nil if !h.mods.hasFlag(Flags.IMPLICIT) && Chars.isOperatorPart(name.decoded.last) => - warning(nameOffset, "multiarg infix syntax looks like a tuple and will be deprecated", WarningCategory.LintMultiargInfix) - case _ => - } DefDef(newmods, name.toTermName, tparams, vparamss, restype, rhs) } signalParseProgress(result.pos) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 48cbabe0cfca..f0f9649df974 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -21,14 +21,14 @@ package tools.nsc package typechecker import scala.collection.mutable +import scala.reflect.internal.{Chars, TypesStats} import scala.reflect.internal.util.{FreshNameCreator, ListOfNil, Statistics, StatisticsStatics} -import scala.reflect.internal.TypesStats +import scala.tools.nsc.Reporting.{MessageFilter, Suppression, WConf, WarningCategory} import scala.util.chaining._ import mutable.ListBuffer import symtab.Flags._ import Mode._ import PartialFunction.cond -import scala.tools.nsc.Reporting.{MessageFilter, Suppression, WConf, WarningCategory} // Suggestion check whether we can do without priming scopes with symbols of outer scopes, // like the IDE does. @@ -2372,7 +2372,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } val tparams1 = ddef.tparams mapConserve typedTypeDef - val vparamss1 = ddef.vparamss mapConserve (_ mapConserve typedValDef) + val vparamss1 = ddef.vparamss.mapConserve(_.mapConserve(typedValDef)) warnTypeParameterShadow(tparams1, meth) @@ -2416,21 +2416,26 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (tpt1.tpe.typeSymbol != NothingClass && !context.returnsSeen && rhs1.tpe.typeSymbol != NothingClass) rhs1 = checkDead(context, rhs1) - if (!isPastTyper && meth.owner.isClass && - meth.paramss.exists(ps => ps.exists(_.hasDefault) && isRepeatedParamType(ps.last.tpe))) - StarWithDefaultError(meth) - if (!isPastTyper) { - for (pp <- meth.paramss ; p <- pp){ - for (n <- p.deprecatedParamName) { + if (meth.owner.isClass && meth.paramss.exists(ps => ps.exists(_.hasDefault) && isRepeatedParamType(ps.last.tpe))) + StarWithDefaultError(meth) + + for (pp <- meth.paramss ; p <- pp) + for (n <- p.deprecatedParamName) if (mexists(meth.paramss)(p1 => p != p1 && (p1.name == n || p1.deprecatedParamName.exists(_ == n)))) DeprecatedParamNameError(p, n) + + if (settings.multiargInfix && !meth.isConstructor && meth.owner.isClass) + meth.paramss match { + case (h :: _ :: _) :: Nil if !h.isImplicit && Chars.isOperatorPart(meth.name.decoded.last) => + context.warning(meth.pos, "multiarg infix syntax looks like a tuple and will be deprecated", WarningCategory.LintMultiargInfix) + case _ => } - } + if (meth.isStructuralRefinementMember) checkMethodStructuralCompatible(ddef) - if (meth.isImplicit && !meth.isSynthetic) meth.info.paramss match { + if (meth.isImplicit && !meth.isSynthetic) meth.paramss match { case List(param) :: _ if !param.isImplicit => checkFeature(ddef.pos, currentRun.runDefinitions.ImplicitConversionsFeature, meth.toString) case _ => diff --git a/test/files/neg/sd503.check b/test/files/neg/sd503.check index 056e0864f27c..35124e8954d4 100644 --- a/test/files/neg/sd503.check +++ b/test/files/neg/sd503.check @@ -10,18 +10,6 @@ sd503.scala:23: error: type mismatch; sd503.scala:9: warning: multiarg infix syntax looks like a tuple and will be deprecated def % (i: Int, j: Int) = i + j // operator, warn ^ -sd503.scala:29: warning: multiarg infix syntax looks like a tuple and will be deprecated - def x_=(i: Int, j: Int): Unit = value = i + j // multiarg, warn - ^ -sd503.scala:34: warning: multiarg infix syntax looks like a tuple and will be deprecated - def x_=(i: Int, j: Int = 1): Unit = devalue = i + j // multiarg, warn - ^ -sd503.scala:46: warning: multiarg infix syntax looks like a tuple and will be deprecated - def ++(i: Int, j: Int): Int = i + j // nowarn! (TODO) - ^ -sd503.scala:54: warning: multiarg infix syntax looks like a tuple and will be deprecated - def +=(x: A, y: A, zs: A*): this.type = addAll(x +: y +: zs) // very multiarg, warn - ^ sd503.scala:13: warning: multiarg infix syntax looks like a tuple and will be deprecated def f1(t: T) = t m (1, 2) // multiarg, warn ^ @@ -31,8 +19,17 @@ sd503.scala:15: warning: multiarg infix syntax looks like a tuple and will be de sd503.scala:19: warning: multiarg infix syntax looks like a tuple and will be deprecated def f5() = c x_= (42, 27) // multiarg, warn ^ +sd503.scala:29: warning: multiarg infix syntax looks like a tuple and will be deprecated + def x_=(i: Int, j: Int): Unit = value = i + j // multiarg, warn + ^ +sd503.scala:34: warning: multiarg infix syntax looks like a tuple and will be deprecated + def x_=(i: Int, j: Int = 1): Unit = devalue = i + j // multiarg, warn + ^ +sd503.scala:54: warning: multiarg infix syntax looks like a tuple and will be deprecated + def +=(x: A, y: A, zs: A*): this.type = addAll(x +: y +: zs) // very multiarg, warn + ^ sd503.scala:59: warning: multiarg infix syntax looks like a tuple and will be deprecated def f[A](as: Embiggen[A], x: A, y: A, z: A): as.type = as += (x, y, z) // very multiarg, warn ^ -9 warnings +8 warnings 2 errors diff --git a/test/files/neg/sd503.scala b/test/files/neg/sd503.scala index 79caea52d8cc..43b36e283855 100644 --- a/test/files/neg/sd503.scala +++ b/test/files/neg/sd503.scala @@ -43,7 +43,7 @@ trait OK { def ?[A: List: reflect.ClassTag] = ??? // nowarn! def calculate(): Int = { - def ++(i: Int, j: Int): Int = i + j // nowarn! (TODO) + def ++(i: Int, j: Int): Int = i + j // nowarn! ++ (42, 17) } } From 559f892843d9ceb35d5dc61fc29cfd05f22c84d3 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Tue, 5 May 2020 02:02:31 -0700 Subject: [PATCH 5/6] Don't warn multiarg infix if deprecated or unused --- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 2 +- test/files/neg/sd503.check | 5 ++++- test/files/neg/sd503.scala | 11 +++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index f0f9649df974..6d303226b26c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2425,7 +2425,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (mexists(meth.paramss)(p1 => p != p1 && (p1.name == n || p1.deprecatedParamName.exists(_ == n)))) DeprecatedParamNameError(p, n) - if (settings.multiargInfix && !meth.isConstructor && meth.owner.isClass) + if (settings.multiargInfix && !meth.isConstructor && meth.owner.isClass && !meth.isDeprecated && !meth.hasAnnotation(UnusedClass)) meth.paramss match { case (h :: _ :: _) :: Nil if !h.isImplicit && Chars.isOperatorPart(meth.name.decoded.last) => context.warning(meth.pos, "multiarg infix syntax looks like a tuple and will be deprecated", WarningCategory.LintMultiargInfix) diff --git a/test/files/neg/sd503.check b/test/files/neg/sd503.check index 35124e8954d4..0b4375eb5784 100644 --- a/test/files/neg/sd503.check +++ b/test/files/neg/sd503.check @@ -31,5 +31,8 @@ sd503.scala:54: warning: multiarg infix syntax looks like a tuple and will be de sd503.scala:59: warning: multiarg infix syntax looks like a tuple and will be deprecated def f[A](as: Embiggen[A], x: A, y: A, z: A): as.type = as += (x, y, z) // very multiarg, warn ^ -8 warnings +sd503.scala:70: warning: multiarg infix syntax looks like a tuple and will be deprecated + def f(x: A, y: A, zs: A*): this.type = this += (x, y, zs: _*) // warn but could defer to deprecation + ^ +9 warnings 2 errors diff --git a/test/files/neg/sd503.scala b/test/files/neg/sd503.scala index 43b36e283855..cb6483953f98 100644 --- a/test/files/neg/sd503.scala +++ b/test/files/neg/sd503.scala @@ -58,3 +58,14 @@ trait Embiggen[A] { trait NotOK { def f[A](as: Embiggen[A], x: A, y: A, z: A): as.type = as += (x, y, z) // very multiarg, warn } + +// Don't warn if deprecated or not used +trait Exceptions[A] { + def addAll(as: Seq[A]): this.type + @deprecated("Quit using old infix style!", since="lately") + def +=(x: A, y: A, zs: A*): this.type = addAll(x +: y +: zs) // nowarn! + @annotation.unused + private def ++=(x: A, y: A, zs: A*): this.type = addAll(x +: y +: zs) // nowarn! + + def f(x: A, y: A, zs: A*): this.type = this += (x, y, zs: _*) // warn but could defer to deprecation +} From 841b88038338e3310065c6db387454ddccceb6b7 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Tue, 5 May 2020 02:30:27 -0700 Subject: [PATCH 6/6] Avoid multiarg infix warning on Subtractable The cost is only incurred when warning. --- src/compiler/scala/tools/nsc/ast/TreeDSL.scala | 5 +++++ src/compiler/scala/tools/nsc/typechecker/Typers.scala | 2 +- src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala | 2 +- test/files/neg/sd503.scala | 5 +++++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala index b82440f1387f..0828e7cc0034 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala @@ -13,6 +13,7 @@ package scala.tools.nsc package ast +import scala.annotation.unused import scala.language.implicitConversions /** A DSL for generating scala code. The goal is that the @@ -82,9 +83,13 @@ trait TreeDSL { def INT_- (other: Tree) = fn(target, getMember(IntClass, nme.MINUS), other) // generic operations on ByteClass, IntClass, LongClass + @unused("avoid warning for multiple parameters") def GEN_| (other: Tree, kind: ClassSymbol) = fn(target, getMember(kind, nme.OR), other) + @unused("avoid warning for multiple parameters") def GEN_& (other: Tree, kind: ClassSymbol) = fn(target, getMember(kind, nme.AND), other) + @unused("avoid warning for multiple parameters") def GEN_== (other: Tree, kind: ClassSymbol) = fn(target, getMember(kind, nme.EQ), other) + @unused("avoid warning for multiple parameters") def GEN_!= (other: Tree, kind: ClassSymbol) = fn(target, getMember(kind, nme.NE), other) /** Apply, Select, Match **/ diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 6d303226b26c..948af40d463a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2425,7 +2425,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (mexists(meth.paramss)(p1 => p != p1 && (p1.name == n || p1.deprecatedParamName.exists(_ == n)))) DeprecatedParamNameError(p, n) - if (settings.multiargInfix && !meth.isConstructor && meth.owner.isClass && !meth.isDeprecated && !meth.hasAnnotation(UnusedClass)) + if (settings.multiargInfix && !meth.isConstructor && meth.owner.isClass && !meth.isDeprecated && !meth.hasAnnotation(UnusedClass) && !meth.ownerChain.exists(_.isDeprecated)) meth.paramss match { case (h :: _ :: _) :: Nil if !h.isImplicit && Chars.isOperatorPart(meth.name.decoded.last) => context.warning(meth.pos, "multiarg infix syntax looks like a tuple and will be deprecated", WarningCategory.LintMultiargInfix) diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala index 04a83d795213..1c6b59c43516 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala @@ -834,7 +834,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { assert(modelFinished) def makeNoDocTemplate(aSym: Symbol, inTpl: TemplateImpl): NoDocTemplateImpl = - noDocTemplatesCache getOrElse (aSym, new NoDocTemplateImpl(aSym, inTpl)) + noDocTemplatesCache.getOrElse(aSym, new NoDocTemplateImpl(aSym, inTpl)) findTemplateMaybe(aSym) getOrElse { val bSym = normalizeTemplate(aSym) diff --git a/test/files/neg/sd503.scala b/test/files/neg/sd503.scala index cb6483953f98..0f154e38e4b1 100644 --- a/test/files/neg/sd503.scala +++ b/test/files/neg/sd503.scala @@ -69,3 +69,8 @@ trait Exceptions[A] { def f(x: A, y: A, zs: A*): this.type = this += (x, y, zs: _*) // warn but could defer to deprecation } +@deprecated("Quit using old infix style!", since="lately") +trait AlsoExceptions[A] { + def addAll(as: Seq[A]): this.type + def +=(x: A, y: A, zs: A*): this.type = addAll(x +: y +: zs) // nowarn! +}