diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala index 5ed7360da3a4..d6e8199d878d 100644 --- a/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/src/dotty/tools/dotc/reporting/Reporter.scala @@ -223,6 +223,8 @@ abstract class Reporter { var warningCount = 0 def hasErrors = errorCount > 0 def hasWarnings = warningCount > 0 + private var errors: List[Error] = Nil + def allErrors = errors /** Have errors been reported by this reporter, or in the * case where this is a StoreReporter, by an outer reporter? @@ -238,7 +240,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 5263925765cf..b8cd88f2d88c 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,140 @@ abstract class CompilerTest { // ========== 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).errorCount + val reporter = processor.process(allArgs) + + 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 = (allArgs filter { + arg => !arg.startsWith("-") && (arg.endsWith(".scala") || arg.endsWith(".java")) + }).toList + 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/abstract-override.scala b/tests/neg/abstract-override.scala index c1ce83725134..4b8c3ace16c5 100644 --- a/tests/neg/abstract-override.scala +++ b/tests/neg/abstract-override.scala @@ -1,6 +1,6 @@ trait T { def foo: Int } -trait T1 extends T { override def foo = super.foo } -trait T2 extends T { override def foo = super.foo } +trait T1 extends T { override def foo = super.foo } // error: method foo in trait T is accessed from super. +trait T2 extends T { override def foo = super.foo } // error: method foo in trait T is accessed from super. object Test extends T2 with T1 { def main(args: Array[String]) = { assert(foo == 3) diff --git a/tests/neg/amp.scala b/tests/neg/amp.scala index da35242a9c97..92062eb0d4e9 100644 --- a/tests/neg/amp.scala +++ b/tests/neg/amp.scala @@ -2,14 +2,14 @@ object Test extends dotty.runtime.LegacyApp { def foo() = { def f: Int = 1 - val x = f _ + val x = f _ // error: not a function: => Int(f) x } def bar(g: => Int) = { - g _ + g _ // error: not a function: => Int(g) } - Console.println((bar{ Console.println("g called"); 42 })()) - Console.println(foo()()) + Console.println((bar{ Console.println("g called"); 42 })()) // error: method bar in object Test$ does not take more parameters + Console.println(foo()()) // error: method foo in object Test$ does not take more parameters } 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..37136b760006 100644 --- a/tests/neg/autoTuplingTest.scala +++ b/tests/neg/autoTuplingTest.scala @@ -1,11 +1,11 @@ import dotty.language.noAutoTupling -object autoTuplingNeg { +object autoTuplingNeg2 { - val x = Some(1, 2) + val x = Some(1, 2) // error: too many arguments for method apply: (x: A)Some[A] x match { - case Some(a, b) => a + b + case Some(a, b) => a + b // error: wrong number of argument patterns for Some // error: not found: b 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/bounds.scala b/tests/neg/bounds.scala index cd6b8d05c9cd..556955877c75 100644 --- a/tests/neg/bounds.scala +++ b/tests/neg/bounds.scala @@ -1,10 +1,10 @@ object Test { def g[B >: String <: Int](x: B): Int = x def main(args: Array[String]): Unit = { - g("foo") + g("foo") // error: Type argument String' does not conform to upper bound Int } def baz[X >: Y, Y <: String](x: X, y: Y) = (x, y) - baz[Int, String](1, "abc") + baz[Int, String](1, "abc") // error: Type argument Int does not conform to lower bound Y } 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 ced6f56b529d..11efea625e90 100644 --- a/tests/neg/cycles.scala +++ b/tests/neg/cycles.scala @@ -22,8 +22,8 @@ class C { class E { class F { - type T <: x.type // error: not stable - val z: x.type = ??? // error: not stable + type T <: x.type // old-error: not stable + val z: x.type = ??? // old-error: not stable } lazy val x: F#T = ??? } @@ -37,6 +37,6 @@ class T2 { type U = X | Int } object T12 { - ??? : (T1 {})#U // error: conflicting bounds - ??? : (T2 {})#U // error: conflicting bounds + ??? : (T1 {})#U // old-error: conflicting bounds + ??? : (T2 {})#U // old-error: conflicting bounds } 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/final-sealed.scala b/tests/neg/final-sealed.scala index 017afd63bd72..79692a61cdae 100644 --- a/tests/neg/final-sealed.scala +++ b/tests/neg/final-sealed.scala @@ -1,4 +1,4 @@ final class A -class B extends A -class C extends Option[Int] +class B extends A // error: cannot extend final class A +class C extends Option[Int] // error: cannot extend sealed class Option in different compilation unit diff --git a/tests/neg/firstError.scala b/tests/neg/firstError.scala index 317adcceddcc..5395aa00c374 100644 --- a/tests/neg/firstError.scala +++ b/tests/neg/firstError.scala @@ -1,4 +1,4 @@ -. +. // error: expected class or object definition -\u890u3084eu +\u890u3084eu // error: error in unicode escape // error: illegal character '\uffff' 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/i1050c.scala b/tests/neg/i1050c.scala index 7998d864da24..19570eb83cdf 100644 --- a/tests/neg/i1050c.scala +++ b/tests/neg/i1050c.scala @@ -4,10 +4,10 @@ object Import { trait B { type L >: Any} trait U { lazy val p: B - locally { val x: p.L = ??? } // error: nonfinal lazy + locally { val x: p.L = ??? } // old-error: nonfinal lazy locally { - import p._ - val x: L = ??? // error: nonfinal lazy + import p._ // error: Import.B(U.this.p) is not a legal path + val x: L = ??? // old-error: nonfinal lazy } } } diff --git a/tests/neg/i324.scala b/tests/neg/i324.scala index 1d03a4d022c4..e36718a554e0 100644 --- a/tests/neg/i324.scala +++ b/tests/neg/i324.scala @@ -1,5 +1,5 @@ class O object O { - val x: this.type = OO.this - val y: O = OO.this + val x: this.type = OO.this // error: OO is not an enclosing class + val y: O = OO.this // error: OO is not an enclosing class } 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 9098b47d6995..f6fa3466db3a 100644 --- a/tests/neg/i50-volatile.scala +++ b/tests/neg/i50-volatile.scala @@ -3,22 +3,22 @@ class 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 // old-error // old-error - def xToString(x: o.X): String = x + def xToString(x: o.X): String = x // old-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/i705-inner-value-class.scala b/tests/neg/i705-inner-value-class.scala index f638b06706e8..82ac962b57be 100644 --- a/tests/neg/i705-inner-value-class.scala +++ b/tests/neg/i705-inner-value-class.scala @@ -1,22 +1,22 @@ class Foo { - class B(val a: Int) extends AnyVal // error + class B(val a: Int) extends AnyVal // error: value class may not be a member of another class } class VCwithBadMembers(val a: Int) extends AnyVal { - def this() = this(1) // error - var x = 0 // error - val y = 2 // error - println("hi") // error + def this() = this(1) // error: value class may not define secondary constructor + var x = 0 // error: value class may not define non-parameter field + val y = 2 // error: value class may not define non-parameter field + println("hi") // error: value class may not contain initialization statements } object Test { class B(val a: Int) extends AnyVal // ok def f = { - class C(val a: Int) extends AnyVal // error + class C(val a: Int) extends AnyVal // error: value class may not be a local class new C(1) } - class B1(val b: Int) extends B(b) -// class D extends B( { class E(val a: Int) extends AnyVal; new E(1) } ) // error + class B1(val b: Int) extends B(b) // error: cannot extend final class B +// class D extends B( { class E(val a: Int) extends AnyVal; new E(1) } ) } diff --git a/tests/neg/i871.scala b/tests/neg/i871.scala index d8e1111a0deb..c85995582c97 100644 --- a/tests/neg/i871.scala +++ b/tests/neg/i871.scala @@ -1,5 +1,5 @@ trait Message { - def first(x: Int) - def second + def first(x: Int) // error: missing return type + def second // error: missing return type 1 } 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/partialApplications.scala b/tests/neg/partialApplications.scala index d186273aa2e3..10cbc556ea79 100644 --- a/tests/neg/partialApplications.scala +++ b/tests/neg/partialApplications.scala @@ -1,11 +1,11 @@ object Test2 { type Histogram = Map[_, Int] // this is now an existential type! - type StringlyHistogram = Histogram[_ >: String] // Error: Test2.Histogram does not take type parameters + type StringlyHistogram = Histogram[_ >: String] // error: Test2.Histogram does not take type parameters - val xs: Histogram[String] = Map[String, Int]() // Error: Test2.Histogram does not take type parameters + val xs: Histogram[String] = Map[String, Int]() // error: Test2.Histogram does not take type parameters - val ys: StringlyHistogram[String] = xs // Error: Test2.StringlyHistogram does not take type parameters + val ys: StringlyHistogram[String] = xs // error: Test2.StringlyHistogram does not take type parameters val zs: StringlyHistogram = xs 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/selfInheritance.scala b/tests/neg/selfInheritance.scala index 993765817dfa..073316de008c 100644 --- a/tests/neg/selfInheritance.scala +++ b/tests/neg/selfInheritance.scala @@ -11,22 +11,22 @@ class C { self: B => } -class D extends A // error +class D extends A // error: illegal inheritance: self type D of class D does not conform to self type B of parent class A -class E extends T // error +class E extends T // error: illegal inheritance: self type E of class E does not conform to self type B of parent trait T object Test { new B() {} - new A() {} // error + new A() {} // error: illegal inheritance: self type A{...} of anonymous class A{...} does not conform to self type B of parent class A - object O extends A // error + object O extends A // error: illegal inheritance: self type Test.O.type of object O$ does not conform to self type B of parent class A - object M extends C // error + object M extends C // error: illegal inheritance: self type Test.M.type of object M$ does not conform to self type B of parent class C } -trait X { self: Y => } +trait X { self: Y => } // error: missing requirement: self type Y & X of trait X does not conform to self type Z of required trait Y trait Y { self: Z => } trait Z diff --git a/tests/neg/selfreq.scala b/tests/neg/selfreq.scala index ff5725bf2dcd..1ca373b4bda3 100644 --- a/tests/neg/selfreq.scala +++ b/tests/neg/selfreq.scala @@ -2,7 +2,7 @@ trait X { self: Y => // error: cannot resolve reference to type (Y & X)(X.this) type T <: self.U - def foo(x: T): T // error: cannot resolve reference to type (Y & X)(X.this).V + def foo(x: T): T // old-error: cannot resolve reference to type (Y & X)(X.this).V def foo(x: String): String } diff --git a/tests/neg/singletons.scala b/tests/neg/singletons.scala index 2155bfe31d2b..502933cc48a9 100644 --- a/tests/neg/singletons.scala +++ b/tests/neg/singletons.scala @@ -3,9 +3,9 @@ object Test { val x = 42 val z: 42 = x // error: x is not final - val n: null = null // error: Null is not a legal singleton type + val n: null = null // error: Null is not a legal singleton type // error: only classes can have declared but undefined members - val sym: 'sym = 'sym // error: Symbol is not a legal singleton type + val sym: 'sym = 'sym // error: Symbol is not a legal singleton type // error: only classes can have declared but undefined members - val foo: s"abc" = "abc" // error: not a legal singleton type + val foo: s"abc" = "abc" // error: not a legal singleton type // error: only classes can have declared but undefined members } diff --git a/tests/neg/subtyping.scala b/tests/neg/subtyping.scala index a4a5a3d19faa..ff3c7a519e8b 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: no implicit argument + } // error: no implicit argument 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: no implicit argument } } 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 9827b19896f6..23a3b6a8b358 100644 --- a/tests/neg/t2994.scala +++ b/tests/neg/t2994.scala @@ -7,7 +7,7 @@ object Naturals { type a[s[_ <: NAT] <: NAT, z <: NAT] = z } final class SUCC[n <: NAT] extends NAT { - type a[s[_ <: NAT] <: NAT, z <: NAT] = s[n#a[s, z]] // error: not a legal path + type a[s[_ <: NAT] <: NAT, z <: NAT] = s[n#a[s, z]] // old-error: not a legal path } type _0 = ZERO type _1 = SUCC[_0] @@ -20,9 +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. // error: wrong number of type arguments - type a[s[_ <: NAT] <: NAT, z <: NAT] = n#a[curry[m#a, s]#f, z] // error: not a legal path // error: not a legal path + trait curry[n[_[_], _], s[_]] { type f[z <: NAT] = n[s, z] } // can't do double param lists: // error: `]' expected but `[` found. // error: wrong number of type arguments + type a[s[_ <: NAT] <: NAT, z <: NAT] = n#a[curry[m#a, s]#f, z] // old-error: not a legal path // old-error: not a legal path } } diff --git a/tests/neg/tailcall/t1672b.scala b/tests/neg/tailcall/t1672b.scala index f05d05c3435f..1ae3d8af86d9 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: TailRec optimisation not applicable try { throw new RuntimeException } catch { @@ -11,7 +11,7 @@ object Test1772B { } @annotation.tailrec - def baz : Nothing = { + def baz : Nothing = { // error: TailRec optimisation not applicable try { throw new RuntimeException } catch { @@ -22,7 +22,7 @@ object Test1772B { } @annotation.tailrec - def boz : Nothing = { + def boz : Nothing = { // error: TailRec optimisation not applicable try { throw new RuntimeException } catch { @@ -31,7 +31,7 @@ object Test1772B { } @annotation.tailrec - def bez : Nothing = { + def bez : Nothing = { // error: TailRec optimisation not applicable 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: TailRec optimisation not applicable if (i == 0) 0 else 1 + (try { throw new RuntimeException } catch { - case _: Throwable => bar(i - 1) + case _: Throwable => bar(i - 1) // old-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/typedIdents.scala b/tests/neg/typedIdents/typedIdents.scala index 4937edfe3a27..56acfc231e3b 100644 --- a/tests/neg/typedIdents/typedIdents.scala +++ b/tests/neg/typedIdents/typedIdents.scala @@ -12,13 +12,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/typers.scala b/tests/neg/typers.scala index 537c4cdb08b6..49742ebbd52e 100644 --- a/tests/neg/typers.scala +++ b/tests/neg/typers.scala @@ -40,8 +40,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 @@ -52,8 +52,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..7321a83827bb 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 when running with -language:noAutoTupling case None => } } diff --git a/tests/pos/t1279a.scala b/tests/pos/t1279a.scala index 6d768d43544b..3edd9b2c438d 100644 --- a/tests/pos/t1279a.scala +++ b/tests/pos/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 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)