summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2008-08-18 14:53:44 +0000
committerMartin Odersky <odersky@gmail.com>2008-08-18 14:53:44 +0000
commitaa43994c9648183a81cba2557dc3188ef6ca341e (patch)
tree4fb2ee654c885db2cc549a7d8ebb1d7c20cdfbdd
parent98ba45e4f615bdb6b04694b3e3099cb1029679ba (diff)
downloadscala-aa43994c9648183a81cba2557dc3188ef6ca341e.tar.gz
scala-aa43994c9648183a81cba2557dc3188ef6ca341e.tar.bz2
scala-aa43994c9648183a81cba2557dc3188ef6ca341e.zip
corrected several problems with error reporting...
corrected several problems with error reporting: positions checked twice, warnings masking errors. Refined solution of forward implicits without5 result type.
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala18
-rwxr-xr-xsrc/compiler/scala/tools/nsc/javac/JavaParsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala14
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala13
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala19
-rwxr-xr-xtest/files/neg/t1049.check4
-rwxr-xr-xtest/files/neg/t1049.scala9
-rwxr-xr-xtest/files/pos/t1001.scala6
-rwxr-xr-xtest/files/pos/t1049.scala9
-rw-r--r--test/pending/pos/t0816.scala12
-rwxr-xr-xtest/pending/pos/t1053.scala6
-rwxr-xr-xtest/pending/pos/t1131.scala4
-rw-r--r--test/pending/run/t1044.scala4
13 files changed, 91 insertions, 29 deletions
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index f536a16a62..bf02e114ab 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -44,19 +44,11 @@ trait CompilationUnits { self: Global =>
*/
val icode: HashSet[icodes.IClass] = new HashSet
- val errorPositions = new HashSet[Position]
-
def error(pos: Position, msg: String) =
- if (inIDE || !(errorPositions contains pos)) {
- if (!inIDE) errorPositions += pos
- reporter.error((pos), msg)
- }
+ reporter.error(pos, msg)
def warning(pos: Position, msg: String) =
- if (inIDE || !(errorPositions contains pos)) {
- if (!inIDE) errorPositions += pos
- reporter.warning((pos), msg)
- }
+ reporter.warning(pos, msg)
def deprecationWarning(pos: Position, msg: String) =
if (settings.deprecation.value) warning(pos, msg)
@@ -67,10 +59,7 @@ trait CompilationUnits { self: Global =>
else currentRun.uncheckedWarnings = true
def incompleteInputError(pos: Position, msg:String) =
- if (inIDE || !(errorPositions contains pos)) {
- if (!inIDE) errorPositions += pos
- reporter.incompleteInputError((pos), msg)
- }
+ reporter.incompleteInputError(pos, msg)
/** Is this about a .java source file? */
lazy val isJava = source.file.name.endsWith(".java")
@@ -81,7 +70,6 @@ trait CompilationUnits { self: Global =>
fresh = null
body = null
depends.clear
- errorPositions.clear
defined.clear
}
}
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 52c1cacb29..f38f0cde1e 100755
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -32,7 +32,7 @@ trait JavaParsers extends JavaScanners {
abstract class JavaParser {
val in: JavaScanner
- protected def posToReport: Int = in.p2g(in.currentPos)
+ protected def posToReport: Int = in.currentPos
protected def freshName(pos : Position, prefix : String): Name
protected implicit def i2p(offset : Int) : Position
private implicit def p2i(pos : Position): Int = pos.offset.getOrElse(-1)
diff --git a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
index 53cbbddcc7..a4f682a715 100644
--- a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
@@ -6,7 +6,7 @@
package scala.tools.nsc.reporters
-import scala.collection.mutable.HashSet
+import scala.collection.mutable.HashMap
import scala.tools.nsc.Settings
import scala.tools.nsc.util.Position
@@ -14,7 +14,7 @@ import scala.tools.nsc.util.Position
* This reporter implements filtering.
*/
abstract class AbstractReporter extends Reporter {
- private val positions = new HashSet[Position]()
+ private val positions = new HashMap[Position, Severity]
override def reset = {
super.reset
@@ -31,13 +31,13 @@ abstract class AbstractReporter extends Reporter {
case INFO =>
if (force || settings.verbose.value) display(pos, msg, severity)
case WARNING =>
- val hidden = testAndLog(pos)
+ val hidden = testAndLog(pos, severity)
if (!settings.nowarnings.value) {
if (!hidden || settings.prompt.value) display(pos, msg, severity)
if (settings.prompt.value) displayPrompt
}
case ERROR =>
- val hidden = testAndLog(pos)
+ val hidden = testAndLog(pos, severity)
if (!hidden || settings.prompt.value) display(pos, msg, severity)
if (settings.prompt.value) displayPrompt
}
@@ -48,11 +48,11 @@ abstract class AbstractReporter extends Reporter {
* @param pos ...
* @return <code>true</code> if <code>pos</code> was already logged.
*/
- private def testAndLog(pos: Position): Boolean = {
+ private def testAndLog(pos: Position, severity: Severity): Boolean = {
if (pos eq null) return false
if (pos.offset.isEmpty) return false
- if (positions contains pos) return true
- positions += pos
+ if ((positions contains pos) && positions(pos) >= severity) return true
+ positions += (pos -> severity)
false
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 51288bab2e..567ff3479e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -197,6 +197,14 @@ trait Infer {
/* -- Error Messages --------------------------------------------------- */
+ private var addendumPos: Position = NoPosition
+ private var addendum: () => String = _
+
+ def setAddendum(pos: Position, msg: () => String) = {
+ addendumPos = pos
+ addendum = msg
+ }
+
def setError[T <: Tree](tree: T): T = {
if (tree.hasSymbol)
if (context.reportGeneralErrors) {
@@ -265,7 +273,10 @@ trait Infer {
def typeError(pos: Position, found: Type, req: Type) {
if (!found.isErroneous && !req.isErroneous) {
- error(pos, typeErrorMsg(found, req))
+ error(pos,
+ typeErrorMsg(found, req)+
+ (if (pos != NoPosition && pos == addendumPos) addendum()
+ else ""))
if (settings.explaintypes.value) explainTypes(found, req)
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 4d57d8bc33..138d2f469d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3648,6 +3648,7 @@ trait Typers { self: Analyzer =>
def comesBefore(sym: Symbol, owner: Symbol) =
sym.pos.offset.getOrElse(0) < owner.pos.offset.getOrElse(Integer.MAX_VALUE) &&
!(owner.ownerChain contains sym)
+
/** Should implicit definition symbol `sym' be considered for applicability testing?
* This is the case if one of the following holds:
* - the symbol's type is initialized
@@ -3666,19 +3667,27 @@ trait Typers { self: Analyzer =>
hasExplicitResultType(sym) ||
comesBefore(sym, context.owner)
}
+ val lateImpls = new ListBuffer[Symbol]
def isApplicable(info: ImplicitInfo): Boolean =
- (true /* for now */ || isValid(info.sym)) &&
!containsError(info.tpe) &&
!(isLocal && shadowed.contains(info.name)) &&
(!isView || info.sym != Predef_identity) &&
tc.typedImplicit(pos, info, pt0, pt, isLocal) != EmptyTree
- def applicableInfos(is: List[ImplicitInfo]) = {
- val result = is filter isApplicable
+ def applicableInfos(is: List[ImplicitInfo]): List[ImplicitInfo] = {
+ val applicable = new ListBuffer[ImplicitInfo]
+ for (i <- is)
+ if (!isValid(i.sym)) lateImpls += i.sym
+ else if (isApplicable(i)) applicable += i
if (isLocal)
for (i <- is) shadowed addEntry i.name
- result
+ applicable.toList
+ }
+ val applicable = implicitInfoss flatMap applicableInfos
+ if (applicable.isEmpty && !lateImpls.isEmpty) {
+ infer.setAddendum(pos, () =>
+ "\n Note: implicit "+lateImpls.first+" is not applicable here"+
+ "\n because it comes after the application point and it lacks an explicit result type")
}
- val applicable = List.flatten(implicitInfoss map applicableInfos)
val best = (NoImplicitInfo /: applicable) ((best, alt) => if (improves(alt, best)) alt else best)
if (best == NoImplicitInfo) EmptyTree
else {
diff --git a/test/files/neg/t1049.check b/test/files/neg/t1049.check
new file mode 100755
index 0000000000..4a63cb175d
--- /dev/null
+++ b/test/files/neg/t1049.check
@@ -0,0 +1,4 @@
+t1049.scala:6: error: not found: value a
+ case a : a.MapTo =>
+ ^
+one error found
diff --git a/test/files/neg/t1049.scala b/test/files/neg/t1049.scala
new file mode 100755
index 0000000000..2f59ed3c09
--- /dev/null
+++ b/test/files/neg/t1049.scala
@@ -0,0 +1,9 @@
+class J {
+ type tttt[a, b] <: _root_.scala.collection.mutable.Map[a, b]
+
+ def r(aa : tttt[String, String]) = {
+ 0 match {
+ case a : a.MapTo =>
+ }
+ }
+}
diff --git a/test/files/pos/t1001.scala b/test/files/pos/t1001.scala
new file mode 100755
index 0000000000..88321e6e8e
--- /dev/null
+++ b/test/files/pos/t1001.scala
@@ -0,0 +1,6 @@
+class Foo;
+
+object Overload{
+ val foo = classOf[Foo].getConstructors()(0)
+ foo.getDeclaringClass
+}
diff --git a/test/files/pos/t1049.scala b/test/files/pos/t1049.scala
new file mode 100755
index 0000000000..dad83579a6
--- /dev/null
+++ b/test/files/pos/t1049.scala
@@ -0,0 +1,9 @@
+class J {
+ type tttt[a, b] <: _root_.scala.collection.mutable.Map[a, b]
+
+ def r(a : tttt[String, String]) = {
+ 0 match {
+ case a : a.MapTo =>
+ }
+ }
+}
diff --git a/test/pending/pos/t0816.scala b/test/pending/pos/t0816.scala
new file mode 100644
index 0000000000..44282ea872
--- /dev/null
+++ b/test/pending/pos/t0816.scala
@@ -0,0 +1,12 @@
+abstract class Atest(val data: String)
+
+case class Btest(override val data: String, val b: boolean) extends Atest(data)
+
+case class Ctest(override val data: String) extends Btest(data, true)
+
+class testCaseClass {
+ def test(x: Atest) = x match {
+ case Ctest(data) => Console.println("C")
+ case Btest(data, b) => Console.println("B")
+ }
+}
diff --git a/test/pending/pos/t1053.scala b/test/pending/pos/t1053.scala
new file mode 100755
index 0000000000..1d4dfb637e
--- /dev/null
+++ b/test/pending/pos/t1053.scala
@@ -0,0 +1,6 @@
+trait T[A] { trait U { type W = A; val x = 3 } }
+
+object Test {
+ val x : ({ type V = T[this.type] })#V = null
+ val y = new x.U { }
+}
diff --git a/test/pending/pos/t1131.scala b/test/pending/pos/t1131.scala
new file mode 100755
index 0000000000..5ef980348d
--- /dev/null
+++ b/test/pending/pos/t1131.scala
@@ -0,0 +1,4 @@
+trait A { self: Any { def p: Any } =>
+ def f(b: => Unit) {}
+ f { p }
+}
diff --git a/test/pending/run/t1044.scala b/test/pending/run/t1044.scala
new file mode 100644
index 0000000000..136cc51af2
--- /dev/null
+++ b/test/pending/run/t1044.scala
@@ -0,0 +1,4 @@
+object Main extends Application{
+ val ducks = Array[AnyRef]("Huey", "Dewey", "Louie")
+ ducks.elements/*.asInstanceOf[Iterator[String]]*/
+}