diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala index 7c5bab673a15..1ae3eb912558 100644 --- a/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/src/dotty/tools/dotc/reporting/Reporter.scala @@ -210,6 +210,8 @@ abstract class Reporter { var warningCount = 0 def hasErrors = errorCount > 0 def hasWarnings = warningCount > 0 + private var errors: List[Error] = Nil + def allErrors = errors val unreportedWarnings = new mutable.HashMap[String, Int] { override def default(key: String) = 0 @@ -220,7 +222,9 @@ abstract class Reporter { d match { case d: ConditionalWarning if !d.enablingOption.value => unreportedWarnings(d.enablingOption.name) += 1 case d: Warning => warningCount += 1 - case d: Error => errorCount += 1 + case d: Error => + errors = d :: errors + errorCount += 1 case d: Info => // nothing to do here // match error if d is something else } diff --git a/test/test/CompilerTest.scala b/test/test/CompilerTest.scala index 09b608f22e1a..8afaa9d9481c 100644 --- a/test/test/CompilerTest.scala +++ b/test/test/CompilerTest.scala @@ -3,9 +3,12 @@ package test import dotty.partest.DPConfig import dotty.tools.dotc.{Main, Bench, Driver} import dotty.tools.dotc.reporting.Reporter +import dotty.tools.dotc.util.SourcePosition +import dotty.tools.dotc.config.CompilerCommand import scala.collection.mutable.ListBuffer -import scala.reflect.io.{ Path, Directory, File => SFile } +import scala.reflect.io.{ Path, Directory, File => SFile, AbstractFile } import scala.tools.partest.nest.{ FileManager, NestUI } +import scala.annotation.tailrec import java.io.{ RandomAccessFile, File => JFile } import org.junit.Test @@ -178,13 +181,138 @@ abstract class CompilerTest extends DottyTest { // ========== HELPERS ============= - private def compileArgs(args: Array[String], xerrors: Int = 0)(implicit defaultOptions: List[String]): Unit = { + private def compileArgs(args: Array[String], xerrors: Int = 0) + (implicit defaultOptions: List[String]): Unit = { val allArgs = args ++ defaultOptions val processor = if (allArgs.exists(_.startsWith("#"))) Bench else Main - val nerrors = processor.process(allArgs, ctx).errorCount + val reporter = processor.process(allArgs, ctx) + + val nerrors = reporter.errorCount assert(nerrors == xerrors, s"Wrong # of errors. Expected: $xerrors, found: $nerrors") + + // NEG TEST + if (xerrors > 0) { + val errorLines = reporter.allErrors.map(_.pos) + // reporter didn't record as many errors as its errorCount says + assert(errorLines.length == nerrors, s"Not enough errors recorded.") + + val allFiles = CompilerCommand.distill(allArgs)(ctx).arguments + val expectedErrorsPerFile = allFiles.map(getErrors(_)) + + // Some compiler errors have an associated source position. Each error + // needs to correspond to a "// error" marker on that line in the source + // file and vice versa. + // Other compiler errors don't have an associated source position. Their + // number should correspond to the total count of "// nopos-error" + // markers in all files + val (errorsByFile, errorsWithoutPos) = errorLines.groupBy(_.source.file).toList.partition(_._1.toString != "") + + // check errors with source position + val foundErrorsPerFile = errorsByFile.map({ case (fileName, errorList) => + val posErrorLinesToNr = errorList.groupBy(_.line).toList.map({ case (line, list) => (line, list.length) }).sortBy(_._1) + ErrorsInFile(fileName.toString, 0, posErrorLinesToNr) + }) + val expectedErrorsPerFileZeroed = expectedErrorsPerFile.map({ + case ErrorsInFile(fileName, _, posErrorLinesToNr) => + ErrorsInFile(fileName.toString, 0, posErrorLinesToNr) + }) + checkErrorsWithPosition(expectedErrorsPerFileZeroed, foundErrorsPerFile) + + // check errors without source position + val expectedNoPos = expectedErrorsPerFile.map(_.noposErrorNr).sum + val foundNoPos = errorsWithoutPos.map(_._2.length).sum + assert(foundNoPos == expectedNoPos, + s"Wrong # of errors without source position. Expected (all files): $expectedNoPos, found (compiler): $foundNoPos") + } } + // ========== NEG TEST HELPERS ============= + + /** Captures the number of nopos-errors in the given file and the number of + * errors with a position, represented as a tuple of source line and number + * of errors on that line. */ + case class ErrorsInFile(fileName: String, noposErrorNr: Int, posErrorLinesToNr: List[(Int, Int)]) + + /** Extracts the errors expected for the given neg test file. */ + def getErrors(fileName: String): ErrorsInFile = { + val content = SFile(fileName).slurp + val (line, rest) = content.span(_ != '\n') + + @tailrec + def checkLine(line: String, rest: String, index: Int, noposAcc: Int, posAcc: List[(Int, Int)]): ErrorsInFile = { + val posErrors = "// ?error".r.findAllIn(line).length + val newPosAcc = if (posErrors > 0) (index, posErrors) :: posAcc else posAcc + val newNoPosAcc = noposAcc + "// ?nopos-error".r.findAllIn(line).length + val (newLine, newRest) = rest.span(_ != '\n') + if (newRest.isEmpty) + ErrorsInFile(fileName.toString, newNoPosAcc, newPosAcc.reverse) + else + checkLine(newLine, newRest.tail, index + 1, newNoPosAcc, newPosAcc) // skip leading '\n' + } + + checkLine(line, rest.tail, 0, 0, Nil) // skip leading '\n' + } + + /** Asserts that the expected and found number of errors correspond, and + * otherwise throws an error with the filename, plus optionally a line + * number if available. */ + def errorMsg(fileName: String, lineNumber: Option[Int], exp: Int, found: Int) = { + val i = lineNumber.map({ i => ":" + (i + 1) }).getOrElse("") + assert(found == exp, s"Wrong # of errors for $fileName$i. Expected (file): $exp, found (compiler): $found") + } + + /** Compares the expected with the found errors and creates a nice error + * message if they don't agree. */ + def checkErrorsWithPosition(expected: List[ErrorsInFile], found: List[ErrorsInFile]): Unit = { + // create nice error messages + expected.diff(found) match { + case Nil => // nothing missing + case ErrorsInFile(fileName, _, expectedLines) :: xs => + found.find(_.fileName == fileName) match { + case None => + // expected some errors, but none found for this file + errorMsg(fileName, None, expectedLines.map(_._2).sum, 0) + case Some(ErrorsInFile(_,_,foundLines)) => + // found wrong number/location of markers for this file + compareLines(fileName, expectedLines, foundLines) + } + } + + found.diff(expected) match { + case Nil => // nothing missing + case ErrorsInFile(fileName, _, foundLines) :: xs => + expected.find(_.fileName == fileName) match { + case None => + // found some errors, but none expected for this file + errorMsg(fileName, None, 0, foundLines.map(_._2).sum) + case Some(ErrorsInFile(_,_,expectedLines)) => + // found wrong number/location of markers for this file + compareLines(fileName, expectedLines, foundLines) + } + } + } + + /** Gives an error message for one line where the expected number of errors and + * the number of compiler errors differ. */ + def compareLines(fileName: String, expectedLines: List[(Int, Int)], foundLines: List[(Int, Int)]) = { + expectedLines.foreach({ case (line, expNr) => + foundLines.find(_._1 == line) match { + case Some((_, `expNr`)) => // this line is ok + case Some((_, foundNr)) => errorMsg(fileName, Some(line), expNr, foundNr) + case None => errorMsg(fileName, Some(line), expNr, 0) + } + }) + foundLines.foreach({ case (line, foundNr) => + expectedLines.find(_._1 == line) match { + case Some((_, `foundNr`)) => // this line is ok + case Some((_, expNr)) => errorMsg(fileName, Some(line), expNr, foundNr) + case None => errorMsg(fileName, Some(line), 0, foundNr) + } + }) + } + + // ========== PARTEST HELPERS ============= + // In particular, don't copy flags from scalac tests private val extensionsToCopy = scala.collection.immutable.HashSet("scala", "java") diff --git a/tests/neg/arrayclone-new.scala b/tests/neg/arrayclone-new.scala index 4e33a7d8cde6..0e42545f8445 100644 --- a/tests/neg/arrayclone-new.scala +++ b/tests/neg/arrayclone-new.scala @@ -7,7 +7,7 @@ object Test extends dotty.runtime.LegacyApp{ } object ObjectArrayClone{ - val it : Array[String] = Array("1", "0"); + val it : Array[String] = Array("1", "0"); // error val cloned = it.clone(); assert(cloned.sameElements(it)); cloned(0) = "0"; @@ -22,7 +22,7 @@ object PolymorphicArrayClone{ assert(it(0) == one) } - testIt(Array("one", "two"), "one", "two"); + testIt(Array("one", "two"), "one", "two"); // error class Mangler[T: ClassTag](ts : T*){ // this will always be a BoxedAnyArray even after we've unboxed its contents. diff --git a/tests/neg/assignments.scala b/tests/neg/assignments.scala index 2314783fe53b..5be107717510 100644 --- a/tests/neg/assignments.scala +++ b/tests/neg/assignments.scala @@ -13,11 +13,11 @@ object assignments { x = x + 1 x *= 2 - x_= = 2 // should give missing arguments + reassignment to val + x_= = 2 // error should give missing arguments + // error reassignment to val } var c = new C - import c._ // should give: prefix is not stable + import c._ // error should give: prefix is not stable x = x + 1 x *= 2 } diff --git a/tests/neg/autoTuplingTest.scala b/tests/neg/autoTuplingTest.scala index d4a698271391..f72dfb635fa5 100644 --- a/tests/neg/autoTuplingTest.scala +++ b/tests/neg/autoTuplingTest.scala @@ -2,10 +2,10 @@ import dotty.language.noAutoTupling object autoTuplingNeg { - val x = Some(1, 2) + val x = Some(1, 2) // error x match { - case Some(a, b) => a + b + case Some(a, b) => a + b // error // error // error case None => } } diff --git a/tests/neg/blockescapesNeg.scala b/tests/neg/blockescapesNeg.scala index 7b448ad2369e..9a0c43b13283 100644 --- a/tests/neg/blockescapesNeg.scala +++ b/tests/neg/blockescapesNeg.scala @@ -1,6 +1,6 @@ object blockescapesNeg { def m0 = { object Foo { class Bar { val field = 2 }} ; new Foo.Bar } - m0.field + m0.field // error class A[T] def m1 = { val x = 1; new A[x.type]} } diff --git a/tests/neg/boundspropagation.scala b/tests/neg/boundspropagation.scala index 42cf67dba385..b545b09da362 100644 --- a/tests/neg/boundspropagation.scala +++ b/tests/neg/boundspropagation.scala @@ -13,7 +13,7 @@ object test2 { def f(x: Any): Tree[Null] = x match { - case y: Tree[_] => y + case y: Tree[_] => y // error } } object test3 { @@ -21,7 +21,7 @@ object test3 { def f(x: Any): Tree[Null] = x match { - case y: Tree[_] => y + case y: Tree[_] => y // error } } @@ -34,11 +34,11 @@ object test4 { class Tree[-S, -T >: Option[S]] def g(x: Any): Tree[_, _ <: Option[N]] = x match { - case y: Tree[_, _] => y + case y: Tree[_, _] => y // error } } } class Test5 { -"": ({ type U = this.type })#U +"": ({ type U = this.type })#U // error // error } diff --git a/tests/neg/companions.scala b/tests/neg/companions.scala index 96b6b4bb6262..4b2cf78df5ab 100644 --- a/tests/neg/companions.scala +++ b/tests/neg/companions.scala @@ -8,7 +8,7 @@ object companionsNeg { { object C { private val p = 1 - println(new C().q) + println(new C().q) // error }} } diff --git a/tests/neg/cycles.scala b/tests/neg/cycles.scala index 0dd24c309ebc..023098a22e8b 100644 --- a/tests/neg/cycles.scala +++ b/tests/neg/cycles.scala @@ -1,21 +1,21 @@ -class Foo[T <: U, U <: T] +class Foo[T <: U, U <: T] // error -class Bar[T >: T] +class Bar[T >: T] // error class A { val x: T = ??? - type T <: x.type + type T <: x.type // error } class B { - type T <: x.type + type T <: x.type // error val x: T = ??? } class C { val x: D#T = ??? class D { - type T <: x.type + type T <: x.type // error val z: x.type = ??? } } @@ -23,17 +23,17 @@ class C { class E { class F { type T <: x.type - val z: x.type = ??? + val z: x.type = ??? // error } val x: F#T = ??? } class T1 { - type X = (U, U) // cycle + type X = (U, U) // cycle // error type U = X & Int } class T2 { - type X = (U, U) // cycle + type X = (U, U) // cycle // error type U = X | Int } object T12 { diff --git a/tests/neg/escapingRefs.scala b/tests/neg/escapingRefs.scala index 9a76eb414684..9e7dfe1e353e 100644 --- a/tests/neg/escapingRefs.scala +++ b/tests/neg/escapingRefs.scala @@ -3,8 +3,8 @@ object O { class B def f[T](x: T, y: T): T = y - val x: A = f(new A { }, new B { }) + val x: A = f(new A { }, new B { }) // error val y = f({ class C { def member: Int = 1 }; new C }, { class C { def member: Int = 1 }; new C }) - val z = y.member + val z = y.member // error } diff --git a/tests/neg/i0091-infpaths.scala b/tests/neg/i0091-infpaths.scala index 917ea49a2a6a..e3b15933ec8a 100644 --- a/tests/neg/i0091-infpaths.scala +++ b/tests/neg/i0091-infpaths.scala @@ -2,7 +2,7 @@ object infpaths { object a { trait T { t => - type M <: t.b.M + type M <: t.b.M // error type T <: a.T val b: t.T } @@ -10,7 +10,7 @@ object infpaths { } val m1: a.x.M = ??? - val m2: a.x.b.M = m1 - val m3: a.x.b.b.M = m2 + val m2: a.x.b.M = m1 // error + val m3: a.x.b.b.M = m2 // error } diff --git a/tests/neg/i0248-inherit-refined.scala b/tests/neg/i0248-inherit-refined.scala index bafcf372bf9f..97b6f5cdab73 100644 --- a/tests/neg/i0248-inherit-refined.scala +++ b/tests/neg/i0248-inherit-refined.scala @@ -1,10 +1,10 @@ object test { class A { type T } type X = A { type T = Int } - class B extends X + class B extends X // error type Y = A & B - class C extends Y + class C extends Y // error type Z = A | B - class D extends Z - abstract class E extends ({ val x: Int }) + class D extends Z // error + abstract class E extends ({ val x: Int }) // error } diff --git a/tests/neg/i0281-null-primitive-conforms.scala b/tests/neg/i0281-null-primitive-conforms.scala index 469e72324d8d..618a0d854dd7 100644 --- a/tests/neg/i0281-null-primitive-conforms.scala +++ b/tests/neg/i0281-null-primitive-conforms.scala @@ -1,6 +1,6 @@ object test { - val b: scala.Boolean = null + val b: scala.Boolean = null // error val c: Unit = null - val d: Float = null - val e: AnyVal = null + val d: Float = null // error + val e: AnyVal = null // error } diff --git a/tests/neg/i0583-skolemize.scala b/tests/neg/i0583-skolemize.scala index e0bb99e5d9f3..c36a4486a259 100644 --- a/tests/neg/i0583-skolemize.scala +++ b/tests/neg/i0583-skolemize.scala @@ -12,7 +12,7 @@ object Test1 { val xs: List[C[_]] = List(c, d) - xs(0).x = xs(1).x + xs(0).x = xs(1).x // error } object Test { @@ -20,7 +20,7 @@ object Test { val f: ListBuffer[Int] = ListBuffer(1,2) val g: ListBuffer[Double] = ListBuffer(3.0,4.0) val lb: ListBuffer[ListBuffer[_]] = ListBuffer(f, g) - lb(0)(0) = lb(1)(0) + lb(0)(0) = lb(1)(0) // error val x: Int = f(0) } } diff --git a/tests/neg/i39.scala b/tests/neg/i39.scala index 250947df9905..df53d98162d9 100644 --- a/tests/neg/i39.scala +++ b/tests/neg/i39.scala @@ -1,7 +1,7 @@ object i39neg { trait B { - type D <: { type T } + type D <: { type T } // error def d: D } @@ -11,7 +11,7 @@ object i39neg { } val d: bc.D = bc.d - val pd: bc.D = bc.pd + val pd: bc.D = bc.pd // error // infinite loop in Typer val asT: d.T = ??? diff --git a/tests/neg/i50-volatile.scala b/tests/neg/i50-volatile.scala index ae31a764c354..11aa74c229c8 100644 --- a/tests/neg/i50-volatile.scala +++ b/tests/neg/i50-volatile.scala @@ -3,22 +3,22 @@ object Test { class Inner } type A <: Base { - type X = String + type X = String // error } type B <: { - type X = Int + type X = Int // error } lazy val o: A & B = ??? - class Client extends o.Inner + class Client extends o.Inner // error // error - def xToString(x: o.X): String = x + def xToString(x: o.X): String = x // error def intToString(i: Int): String = xToString(i) } object Test2 { - import Test.o._ + import Test.o._ // error def xToString(x: X): String = x diff --git a/tests/neg/instantiateAbstract.scala b/tests/neg/instantiateAbstract.scala index 1e119a8b57e2..10eeac64d9e2 100644 --- a/tests/neg/instantiateAbstract.scala +++ b/tests/neg/instantiateAbstract.scala @@ -24,7 +24,7 @@ object Test { new TT // error - new A // error + new A // the following are OK in Typer but would be caught later in RefChecks @@ -36,3 +36,5 @@ object Test { object OO extends AA } + +// nopos-error: "A does not conform to its self type B; cannot be instantiated" diff --git a/tests/neg/over.scala b/tests/neg/over.scala index 80ce7d09f4c3..1644dff24483 100644 --- a/tests/neg/over.scala +++ b/tests/neg/over.scala @@ -4,14 +4,14 @@ trait T { class C extends T { - val x = 2 - override val y = 2 + val x = 2 // error + override val y = 2 // error } class D extends T { - def x(): String = "" + def x(): String = "" // error } diff --git a/tests/neg/overrides.scala b/tests/neg/overrides.scala index 9fe06d93020c..f4316fa2996e 100644 --- a/tests/neg/overrides.scala +++ b/tests/neg/overrides.scala @@ -8,7 +8,7 @@ } trait FooB extends FooA { type A <: Ax; - trait Ax extends super.Ax { def xxx : Int; } + trait Ax extends super.Ax { def xxx : Int; } // error abstract class InnerB extends InnerA { // type B <: A; val a : A = doB; @@ -31,7 +31,7 @@ package p2 { // all being in the same package compiles fine } abstract class T3 extends T2 { - class A { + class A { // error bug() } } @@ -45,7 +45,7 @@ class A[T] { class B extends A[Int] { - def f(x: Int)(y: Int) = y + def f(x: Int)(y: Int) = y // error f(2)() @@ -55,7 +55,7 @@ class X { def f: A[Int] = ??? } class Y extends X { - def f: A[Int] = ??? + def f: A[Int] = ??? // error } @@ -66,18 +66,18 @@ class X1 { def f(): A1 = ??? } class Y1 extends X1 { - override def f(): B1 = ??? + override def f(): B1 = ??? // error } class X2 { type T = A1 } class Y2 extends X2 { - type T = B1 + type T = B1 // error } class X3 { - override type T = A1 + override type T = A1 // error } package p3 { @@ -97,14 +97,14 @@ trait TOverrider { this: TCommon => override def f = "in TOverrider" // The overridden self-type member... } -class C2 extends C1 with TOverrider // ... fails to override, here. +class C2 extends C1 with TOverrider // ... fails to override, here. // error } package p4 { abstract class C[T] { def head: T } - case class D[T](head: Int) extends C[T] + case class D[T](head: Int) extends C[T] // error } @@ -114,10 +114,10 @@ class A { } class B extends A { - override val m: Int = 42 + override val m: Int = 42 // error } class C extends A { - override def m: Int = 42 + override def m: Int = 42 // error } } diff --git a/tests/neg/privates.scala b/tests/neg/privates.scala index 404e5c2d8ad0..9209f0cdc19a 100644 --- a/tests/neg/privates.scala +++ b/tests/neg/privates.scala @@ -5,7 +5,7 @@ trait T { } class C { self: T => - foo - bar + foo // error + bar // error } diff --git a/tests/neg/subtyping.scala b/tests/neg/subtyping.scala index a4a5a3d19faa..03ff39be40dd 100644 --- a/tests/neg/subtyping.scala +++ b/tests/neg/subtyping.scala @@ -5,10 +5,10 @@ class A extends B object Test { def test1(): Unit = { - implicitly[B#X <:< A#X] + implicitly[B#X <:< A#X] // error } def test2(): Unit = { - val a : { type T; type U } = ??? - implicitly[a.T <:< a.U] + val a : { type T; type U } = ??? // error // error + implicitly[a.T <:< a.U] // error } } diff --git a/tests/neg/t0273.scala b/tests/neg/t0273.scala index 10f4268288fb..0fba8a8a49d7 100644 --- a/tests/neg/t0273.scala +++ b/tests/neg/t0273.scala @@ -2,6 +2,6 @@ class A object Test { def a = () => () -def a[T] = (p:A) => () +def a[T] = (p:A) => () // error def main(args: Array[String]) = () } diff --git a/tests/neg/t1279a.scala b/tests/neg/t1279a.scala index 6d768d43544b..78633ec3c479 100644 --- a/tests/neg/t1279a.scala +++ b/tests/neg/t1279a.scala @@ -4,12 +4,12 @@ abstract class M { type T final type selfType = M {type T <: self.T} - type actualSelfType >: self.type <: selfType // this no longer compiles because self.type is not a subtype of selfType + type actualSelfType >: self.type <: selfType // error: this no longer compiles because self.type is not a subtype of selfType def next: selfType // I don't understand why this doesn't compile, but that's a separate matter - // error: method all2 cannot be accessed in M.this.selfType + // Error: method all2 cannot be accessed in M.this.selfType // because its instance type => Stream[M{type T <: M.this.selfType#T}] // contains a malformed type: M.this.selfType#T def all2: Stream[M {type T <: self.T}] = Stream.cons(self: actualSelfType, next.all2) diff --git a/tests/neg/t1569-failedAvoid.scala b/tests/neg/t1569-failedAvoid.scala index 9d0fbb37a3b8..45bb96f36002 100644 --- a/tests/neg/t1569-failedAvoid.scala +++ b/tests/neg/t1569-failedAvoid.scala @@ -5,5 +5,5 @@ object Bug { class C { type T } def foo(x: Int)(y: C)(z: y.T): Unit = {} - foo(3)(new C { type T = String })("hello") + foo(3)(new C { type T = String })("hello") // error } diff --git a/tests/neg/t1843-variances.scala b/tests/neg/t1843-variances.scala index e9b5c5d2d902..a6bdd686feec 100644 --- a/tests/neg/t1843-variances.scala +++ b/tests/neg/t1843-variances.scala @@ -6,7 +6,7 @@ object Crash { trait UpdateType[A] - case class StateUpdate[+A](updateType : UpdateType[A], value : A) + case class StateUpdate[+A](updateType : UpdateType[A], value : A) // error case object IntegerUpdateType extends UpdateType[Integer] //However this method will cause a crash diff --git a/tests/neg/t2660.scala b/tests/neg/t2660.scala index 85e318915db5..17fe262585ab 100644 --- a/tests/neg/t2660.scala +++ b/tests/neg/t2660.scala @@ -22,7 +22,7 @@ class A[T](x: T) { object T { def main(args: Array[String]): Unit = { implicit def g2h(g: G): H = new H - new A[Int](new H, 23) + new A[Int](new H, 23) // error // in the context here, either secondary constructor is applicable // to the other, due to the implicit in scope. So the call is ambiguous. } @@ -40,7 +40,7 @@ object X { object T2 { def main(args: Array[String]): Unit = { implicit def g2h(g: G): H = new H - X.f(new H, 23) + X.f(new H, 23) // error } } diff --git a/tests/neg/t2994.scala b/tests/neg/t2994.scala index 9e9c4ec087b0..9a638451aaa9 100644 --- a/tests/neg/t2994.scala +++ b/tests/neg/t2994.scala @@ -20,8 +20,8 @@ object Naturals { // crashes scala-2.8.0 beta1 trait MUL[n <: NAT, m <: NAT] extends NAT { - trait curry[n[_[_], _], s[_]] { type f[z <: NAT] = n[s, z] } // can't do double param lists: - // error: `]' expected but `[` found. + trait curry[n[_[_], _], s[_]] { type f[z <: NAT] = n[s, z] } // can't do double param lists: // error // error + // Error: `]' expected but `[` found. type a[s[_ <: NAT] <: NAT, z <: NAT] = n#a[curry[m#a, s]#f, z] } diff --git a/tests/neg/tailcall/t1672b.scala b/tests/neg/tailcall/t1672b.scala index f05d05c3435f..2c2ec9b410da 100644 --- a/tests/neg/tailcall/t1672b.scala +++ b/tests/neg/tailcall/t1672b.scala @@ -1,6 +1,6 @@ object Test1772B { @annotation.tailrec - def bar : Nothing = { + def bar : Nothing = { // error try { throw new RuntimeException } catch { @@ -11,7 +11,7 @@ object Test1772B { } @annotation.tailrec - def baz : Nothing = { + def baz : Nothing = { // error try { throw new RuntimeException } catch { @@ -22,7 +22,7 @@ object Test1772B { } @annotation.tailrec - def boz : Nothing = { + def boz : Nothing = { // error try { throw new RuntimeException } catch { @@ -31,7 +31,7 @@ object Test1772B { } @annotation.tailrec - def bez : Nothing = { + def bez : Nothing = { // error try { bez } finally { @@ -41,12 +41,12 @@ object Test1772B { // the `liftedTree` local method will prevent a tail call here. @annotation.tailrec - def bar(i : Int) : Int = { + def bar(i : Int) : Int = { // error if (i == 0) 0 else 1 + (try { throw new RuntimeException } catch { - case _: Throwable => bar(i - 1) + case _: Throwable => bar(i - 1) // error }) } } diff --git a/tests/neg/tailcall/t3275.scala b/tests/neg/tailcall/t3275.scala index 18e38a1a97c2..df6155035952 100644 --- a/tests/neg/tailcall/t3275.scala +++ b/tests/neg/tailcall/t3275.scala @@ -1,3 +1,3 @@ object Test { - @annotation.tailrec def foo() = 5 + @annotation.tailrec def foo() = 5 // error } diff --git a/tests/neg/tailcall/t6574.scala b/tests/neg/tailcall/t6574.scala index e81c8cd07766..7030b3b4ad05 100644 --- a/tests/neg/tailcall/t6574.scala +++ b/tests/neg/tailcall/t6574.scala @@ -1,6 +1,6 @@ class Bad[X, Y](val v: Int) extends AnyVal { - @annotation.tailrec final def notTailPos[Z](a: Int)(b: String): Unit = { - this.notTailPos[Z](a)(b) + @annotation.tailrec final def notTailPos[Z](a: Int)(b: String): Unit = { // error + this.notTailPos[Z](a)(b) // error println("tail") } diff --git a/tests/neg/tailcall/tailrec-2.scala b/tests/neg/tailcall/tailrec-2.scala index bc594293d7f6..b5edab4c701a 100644 --- a/tests/neg/tailcall/tailrec-2.scala +++ b/tests/neg/tailcall/tailrec-2.scala @@ -13,7 +13,7 @@ class Bop2[+A](val element: A) extends Super[A] { @annotation.tailrec final def f[B >: A](mem: List[B]): List[B] = (null: Bop2[A]).f(mem) } object Bop3 extends Super[Nothing] { - @annotation.tailrec final def f[B](mem: List[B]): List[B] = (???: Bop3.type).f(mem) + @annotation.tailrec final def f[B](mem: List[B]): List[B] = (???: Bop3.type).f(mem) // error // error } class Bop4[+A](val element: A) extends Super[A] { @annotation.tailrec final def f[B >: A](mem: List[B]): List[B] = Other.f[A].f(mem) diff --git a/tests/neg/tailcall/tailrec-3.scala b/tests/neg/tailcall/tailrec-3.scala index 20361658eace..b0c56061527d 100644 --- a/tests/neg/tailcall/tailrec-3.scala +++ b/tests/neg/tailcall/tailrec-3.scala @@ -1,9 +1,9 @@ import annotation.tailrec object Test { - @tailrec private def quux(xs: List[String]): List[String] = quux(quux(xs)) + @tailrec private def quux(xs: List[String]): List[String] = quux(quux(xs)) // error @tailrec private def quux2(xs: List[String]): List[String] = xs match { - case x1 :: x2 :: rest => quux2(x1 :: quux2(rest)) + case x1 :: x2 :: rest => quux2(x1 :: quux2(rest)) // error case _ => Nil } @tailrec private def quux3(xs: List[String]): Boolean = xs match { diff --git a/tests/neg/tailcall/tailrec.scala b/tests/neg/tailcall/tailrec.scala index 83a0c1a9e609..49d71ce13eb3 100644 --- a/tests/neg/tailcall/tailrec.scala +++ b/tests/neg/tailcall/tailrec.scala @@ -40,19 +40,19 @@ class Winners { object Failures { @tailrec - def facfail(n: Int): Int = + def facfail(n: Int): Int = // error if (n == 0) 1 - else n * facfail(n - 1) + else n * facfail(n - 1) // error } class Failures { // not private, not final - @tailrec def fail1(x: Int): Int = fail1(x) + @tailrec def fail1(x: Int): Int = fail1(x) // error // a typical between-chair-and-keyboard error - @tailrec final def fail2[T](xs: List[T]): List[T] = xs match { + @tailrec final def fail2[T](xs: List[T]): List[T] = xs match { // error case Nil => Nil - case x :: xs => x :: fail2[T](xs) + case x :: xs => x :: fail2[T](xs) // error } // unsafe @@ -60,6 +60,6 @@ class Failures { // unsafe class Tom[T](x: Int) { - @tailrec final def fail4[U](other: Tom[U], x: Int): Int = other.fail4[U](other, x - 1) + @tailrec final def fail4[U](other: Tom[U], x: Int): Int = other.fail4[U](other, x - 1) // error // error } } diff --git a/tests/neg/traitParamsTyper.scala b/tests/neg/traitParamsTyper.scala index f87ba3691d7f..e97906b50cdb 100644 --- a/tests/neg/traitParamsTyper.scala +++ b/tests/neg/traitParamsTyper.scala @@ -6,7 +6,7 @@ class C(x: Int) extends T() // error trait U extends C with T -trait V extends C(1) with T(2) // two errors +trait V extends C(1) with T(2) // error // error trait W extends T(3) // error diff --git a/tests/neg/typedIdents.scala b/tests/neg/typedIdents.scala index cb7cca743557..efb0ee9a23ed 100644 --- a/tests/neg/typedIdents.scala +++ b/tests/neg/typedIdents.scala @@ -18,13 +18,13 @@ package P { // `X' bound by package clause println("L12: " + x) // `x' refers to constant `3' here locally { import Q.X._ // `x' and `y' bound by wildcard import - println("L14: " + x) // reference to `x' is ambiguous here + println("L14: " + x) // error: reference to `x' is ambiguous here import X.y // `y' bound by explicit import println("L16: " + y) // `y' refers to `Q.X.y' here locally { import P.X._ // `x' and `y' bound by wildcard import val x = "abc" // `x' bound by local definition - println("L19: " + y) // reference to `y' is ambiguous here + println("L19: " + y) // error: reference to `y' is ambiguous here println("L20: " + x) // `x' refers to string ``abc'' here } } diff --git a/tests/neg/typedapply.scala b/tests/neg/typedapply.scala index b80281c9ff67..6d418b629e54 100644 --- a/tests/neg/typedapply.scala +++ b/tests/neg/typedapply.scala @@ -2,16 +2,16 @@ object typedapply { def foo[X, Y](x: X, y: Y) = (x, y) - foo[Int](1, "abc") + foo[Int](1, "abc") // error - foo[Int, String, String](1, "abc") + foo[Int, String, String](1, "abc") // error def bar(x: Int) = x - bar[Int](1) + bar[Int](1) // error def baz[X >: Y, Y <: String](x: X, y: Y) = (x, y) - baz[Int, String](1, "abc") + baz[Int, String](1, "abc") // error } diff --git a/tests/neg/typers.scala b/tests/neg/typers.scala index b5bd1fa2c129..9d7922ce049f 100644 --- a/tests/neg/typers.scala +++ b/tests/neg/typers.scala @@ -22,8 +22,8 @@ object typers { val z: Int def z(): String // error: double def - def f(x: Any) = () // error: double def - def f(x: AnyRef): AnyRef + def f(x: Any) = () + def f(x: AnyRef): AnyRef // error: double def def g(x: Object): Unit def g[T](x: T): T = x // error: double def @@ -34,8 +34,8 @@ object typers { object returns { - def foo(x: Int) = { // error: has return; needs result type - return 3 + def foo(x: Int) = { + return 3 // error: has return; needs result type } return 4 // error: return outside method definition @@ -46,8 +46,8 @@ object typers { if (n == 0) acc else factorial(acc * n, n - 1) // error: cyclic reference - def foo(x: Int) = x // error: cyclic reference - def foo() = foo(1) + def foo(x: Int) = x + def foo() = foo(1) // error: cyclic reference } diff --git a/tests/neg/typetest.scala b/tests/neg/typetest.scala index 27ecd25b25d0..a49e30054b9f 100644 --- a/tests/neg/typetest.scala +++ b/tests/neg/typetest.scala @@ -2,6 +2,6 @@ object Test { val i: Int = 1 - println(i.isInstanceOf[Object]) + println(i.isInstanceOf[Object]) // error } diff --git a/tests/neg/variances.scala b/tests/neg/variances.scala index 30390ad22fb4..71ee504bcda0 100644 --- a/tests/neg/variances.scala +++ b/tests/neg/variances.scala @@ -5,7 +5,7 @@ class Foo[+A: ClassTag](x: A) { private[this] val elems: Array[A] = Array(x) - def f[B](x: Array[B] = elems): Array[B] = x // (1) should give a variance error here or ... + def f[B](x: Array[B] = elems): Array[B] = x // error (1) should give a variance error here or ... } @@ -25,7 +25,7 @@ class Outer[+A](x: A) { def getElem: A = elem - class Inner(constrParam: A) { // (2) should give a variance error here or ... + class Inner(constrParam: A) { // error (2) should give a variance error here or ... elem = constrParam } diff --git a/tests/neg/zoo.scala b/tests/neg/zoo.scala index 6a3e4ca0b2bc..3d9b77b727eb 100644 --- a/tests/neg/zoo.scala +++ b/tests/neg/zoo.scala @@ -1,25 +1,25 @@ object Test { type Meat = { - type IsMeat = Any + type IsMeat = Any // error } type Grass = { - type IsGrass = Any + type IsGrass = Any // error } type Animal = { - type Food - def eats(food: Food): Unit - def gets: Food + type Food // error + def eats(food: Food): Unit // error + def gets: Food // error } type Cow = { - type IsMeat = Any - type Food <: Grass - def eats(food: Grass): Unit - def gets: Grass + type IsMeat = Any // error + type Food <: Grass // error + def eats(food: Grass): Unit // error + def gets: Grass // error } type Lion = { - type Food = Meat - def eats(food: Meat): Unit - def gets: Meat + type Food = Meat // error + def eats(food: Meat): Unit // error + def gets: Meat // error } def newMeat: Meat = new { type IsMeat = Any diff --git a/tests/pos/autoTuplingTest.scala b/tests/pos/autoTuplingTest.scala index 523411a1a410..c5bb84e954f4 100644 --- a/tests/pos/autoTuplingTest.scala +++ b/tests/pos/autoTuplingTest.scala @@ -1,9 +1,9 @@ object autoTupling { - val x = Some(1, 2) + val x = Some(1, 2) // error when running with -language:noAutoTupling x match { - case Some(a, b) => a + b + case Some(a, b) => a + b // error // error // error when running with -language:noAutoTupling case None => } }