summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-10-08 22:09:01 +0200
committerJason Zaugg <jzaugg@gmail.com>2013-10-09 09:41:34 +0200
commit7e4a97e532a9adcd0a6d014d948702aebec3541f (patch)
tree0aa8d4b58c2b3dc97c7cfb3a9aae2f3c16eea732
parentd0af55ce1ffb9d77e6a604edb41cda2b955e9f02 (diff)
downloadscala-7e4a97e532a9adcd0a6d014d948702aebec3541f.tar.gz
scala-7e4a97e532a9adcd0a6d014d948702aebec3541f.tar.bz2
scala-7e4a97e532a9adcd0a6d014d948702aebec3541f.zip
SI-7895 Issue all buffered errors after silent mode.
Rather than just the first. For example, `foo(wizzle, wuzzle, woggle)` should report all three not-found symbols.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala44
-rw-r--r--test/files/neg/names-defaults-neg.check16
-rw-r--r--test/files/neg/t4515.check12
-rw-r--r--test/files/neg/t556.check5
-rw-r--r--test/files/neg/t5572.check7
-rw-r--r--test/files/neg/t6829.check22
-rw-r--r--test/files/neg/t7895b.check7
-rw-r--r--test/files/neg/t7895b.scala5
-rw-r--r--test/files/neg/typeerror.check7
10 files changed, 101 insertions, 25 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index abc5363423..5e5619d034 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -329,6 +329,7 @@ trait Contexts { self: Analyzer =>
/** The first error, if any, in the report buffer */
def firstError: Option[AbsTypeError] = reportBuffer.firstError
+ def errors: Seq[AbsTypeError] = reportBuffer.errors
/** Does the report buffer contain any errors? */
def hasErrors = reportBuffer.hasErrors
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index e7371fa26b..0e4797d011 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -79,12 +79,19 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case SilentResultValue(value) if !p(value) => SilentTypeError(TypeErrorWrapper(new TypeError(NoPosition, "!p")))
case _ => this
}
- @inline final def orElse[T1 >: T](f: AbsTypeError => T1): T1 = this match {
+ @inline final def orElse[T1 >: T](f: Seq[AbsTypeError] => T1): T1 = this match {
case SilentResultValue(value) => value
- case SilentTypeError(err) => f(err)
+ case s : SilentTypeError => f(s.errors)
}
}
- case class SilentTypeError(err: AbsTypeError) extends SilentResult[Nothing] { }
+ class SilentTypeError private(val errors: Seq[AbsTypeError]) extends SilentResult[Nothing] {
+ def err: AbsTypeError = errors.head
+ }
+ object SilentTypeError {
+ def apply(errors: AbsTypeError*): SilentTypeError = new SilentTypeError(errors)
+ def unapply(error: SilentTypeError): Option[AbsTypeError] = error.errors.headOption
+ }
+
case class SilentResultValue[+T](value: T) extends SilentResult[T] { }
def newTyper(context: Context): Typer = new NormalTyper(context)
@@ -682,14 +689,13 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
context.undetparams = context1.undetparams
context.savedTypeBounds = context1.savedTypeBounds
context.namedApplyBlockInfo = context1.namedApplyBlockInfo
- context1.firstError match {
- case Some(err) =>
- stopStats()
- SilentTypeError(err)
- case None =>
- // If we have a successful result, emit any warnings it created.
- context1.flushAndIssueWarnings()
- SilentResultValue(result)
+ if (context1.hasErrors) {
+ stopStats()
+ SilentTypeError(context1.errors: _*)
+ } else {
+ // If we have a successful result, emit any warnings it created.
+ context1.flushAndIssueWarnings()
+ SilentResultValue(result)
}
} else {
assert(context.bufferErrors || isPastTyper, "silent mode is not available past typer")
@@ -1258,9 +1264,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
reportError
}
- silent(_.adaptToMember(qual, HasMember(name), reportAmbiguous = false)) orElse (err =>
+ silent(_.adaptToMember(qual, HasMember(name), reportAmbiguous = false)) orElse (errs =>
onError {
- if (reportAmbiguous) context issue err
+ if (reportAmbiguous) errs foreach (context issue _)
setError(tree)
}
)
@@ -3786,7 +3792,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
}
}
- def wrapErrors(tree: Tree, typeTree: Typer => Tree): Tree = silent(typeTree) orElse (err => DynamicRewriteError(tree, err))
+ def wrapErrors(tree: Tree, typeTree: Typer => Tree): Tree = silent(typeTree) orElse (err => DynamicRewriteError(tree, err.head))
}
def typed1(tree: Tree, mode: Mode, pt: Type): Tree = {
@@ -4173,7 +4179,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
def tryTypedApply(fun: Tree, args: List[Tree]): Tree = {
val start = if (Statistics.canEnable) Statistics.startTimer(failedApplyNanos) else null
- def onError(typeError: AbsTypeError): Tree = {
+ def onError(typeErrors: Seq[AbsTypeError]): Tree = {
if (Statistics.canEnable) Statistics.stopTimer(failedApplyNanos, start)
// If the problem is with raw types, copnvert to existentials and try again.
@@ -4198,13 +4204,13 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case TypeApply(fun, args) => treesInResult(fun) ++ args.flatMap(treesInResult)
case _ => Nil
})
- def errorInResult(tree: Tree) = treesInResult(tree) exists (_.pos == typeError.errPos)
+ def errorInResult(tree: Tree) = treesInResult(tree) exists (err => typeErrors.exists(_.errPos == err.pos))
- val retry = (typeError.errPos != null) && (fun :: tree :: args exists errorInResult)
+ val retry = (typeErrors.forall(_.errPos != null)) && (fun :: tree :: args exists errorInResult)
typingStack.printTyping({
val funStr = ptTree(fun) + " and " + (args map ptTree mkString ", ")
if (retry) "second try: " + funStr
- else "no second try: " + funStr + " because error not in result: " + typeError.errPos+"!="+tree.pos
+ else "no second try: " + funStr + " because error not in result: " + typeErrors.head.errPos+"!="+tree.pos
})
if (retry) {
val Select(qual, name) = fun
@@ -4220,7 +4226,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case _ => ()
}
}
- issue(typeError)
+ typeErrors foreach issue
setError(treeCopy.Apply(tree, fun, args))
}
diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check
index cdc12c2490..880ddc4327 100644
--- a/test/files/neg/names-defaults-neg.check
+++ b/test/files/neg/names-defaults-neg.check
@@ -7,6 +7,11 @@ names-defaults-neg.scala:5: error: type mismatch;
required: Int
test1(b = 2, a = "#")
^
+names-defaults-neg.scala:5: error: type mismatch;
+ found : Int(2)
+ required: String
+ test1(b = 2, a = "#")
+ ^
names-defaults-neg.scala:8: error: positional after named argument.
test1(b = "(*", 23)
^
@@ -122,6 +127,12 @@ names-defaults-neg.scala:131: error: reference to var2 is ambiguous; it is both
names-defaults-neg.scala:134: error: missing parameter type for expanded function ((x$1) => a = x$1)
val taf2: Int => Unit = testAnnFun(a = _, b = get("+"))
^
+names-defaults-neg.scala:134: error: not found: value a
+ val taf2: Int => Unit = testAnnFun(a = _, b = get("+"))
+ ^
+names-defaults-neg.scala:134: error: not found: value get
+ val taf2: Int => Unit = testAnnFun(a = _, b = get("+"))
+ ^
names-defaults-neg.scala:135: error: parameter 'a' is already specified at parameter position 1
val taf3 = testAnnFun(b = _: String, a = get(8))
^
@@ -131,6 +142,9 @@ names-defaults-neg.scala:136: error: missing parameter type for expanded functio
names-defaults-neg.scala:136: error: missing parameter type for expanded function ((x$4) => b = x$4)
val taf4: (Int, String) => Unit = testAnnFun(_, b = _)
^
+names-defaults-neg.scala:136: error: not found: value b
+ val taf4: (Int, String) => Unit = testAnnFun(_, b = _)
+ ^
names-defaults-neg.scala:144: error: variable definition needs type because 'x' is used as a named argument in its body.
def t3 { var x = t.f(x = 1) }
^
@@ -168,4 +182,4 @@ names-defaults-neg.scala:180: error: reference to x is ambiguous; it is both a m
class u18 { var x: Int = u.f(x = 1) }
^
four warnings found
-42 errors found
+46 errors found
diff --git a/test/files/neg/t4515.check b/test/files/neg/t4515.check
index 64e7cc1ca7..708fcfbd29 100644
--- a/test/files/neg/t4515.check
+++ b/test/files/neg/t4515.check
@@ -3,4 +3,14 @@ t4515.scala:37: error: type mismatch;
required: _$2
handler.onEvent(target, ctx.getEvent, node, ctx)
^
-one error found
+t4515.scala:37: error: type mismatch;
+ found : Main.DerivedPushNode[_$1] where type _$1
+ required: Main.PushNode[_$2]
+ handler.onEvent(target, ctx.getEvent, node, ctx)
+ ^
+t4515.scala:37: error: type mismatch;
+ found : Main.PushEventContext[_$1] where type _$1
+ required: Main.PushEventContext[_$2]
+ handler.onEvent(target, ctx.getEvent, node, ctx)
+ ^
+three errors found
diff --git a/test/files/neg/t556.check b/test/files/neg/t556.check
index 5135dc92ef..30cc296b35 100644
--- a/test/files/neg/t556.check
+++ b/test/files/neg/t556.check
@@ -1,4 +1,7 @@
t556.scala:3: error: missing parameter type
def g:Int = f((x,y)=>x)
^
-one error found
+t556.scala:3: error: missing parameter type
+ def g:Int = f((x,y)=>x)
+ ^
+two errors found
diff --git a/test/files/neg/t5572.check b/test/files/neg/t5572.check
index 7b1e290861..3c9adf41cd 100644
--- a/test/files/neg/t5572.check
+++ b/test/files/neg/t5572.check
@@ -3,9 +3,14 @@ t5572.scala:16: error: type mismatch;
required: A
Z.transf(a, b) match {
^
+t5572.scala:16: error: type mismatch;
+ found : A
+ required: B
+ Z.transf(a, b) match {
+ ^
t5572.scala:18: error: type mismatch;
found : A
required: B
run(sth, b)
^
-two errors found
+three errors found
diff --git a/test/files/neg/t6829.check b/test/files/neg/t6829.check
index c7c641844e..a0b43e3b52 100644
--- a/test/files/neg/t6829.check
+++ b/test/files/neg/t6829.check
@@ -20,11 +20,31 @@ t6829.scala:50: error: type mismatch;
required: _53.State where val _53: G
val r = rewards(agent).r(s,a,s2)
^
+t6829.scala:50: error: type mismatch;
+ found : a.type (with underlying type T2)
+ required: _53.Action where val _53: G
+ val r = rewards(agent).r(s,a,s2)
+ ^
+t6829.scala:50: error: type mismatch;
+ found : s2.type (with underlying type T3)
+ required: _53.State where val _53: G
+ val r = rewards(agent).r(s,a,s2)
+ ^
t6829.scala:51: error: type mismatch;
found : s.type (with underlying type T1)
required: _50.State
agent.learn(s,a,s2,r): G#Agent
^
+t6829.scala:51: error: type mismatch;
+ found : a.type (with underlying type T2)
+ required: _50.Action
+ agent.learn(s,a,s2,r): G#Agent
+ ^
+t6829.scala:51: error: type mismatch;
+ found : s2.type (with underlying type T3)
+ required: _50.State
+ agent.learn(s,a,s2,r): G#Agent
+ ^
t6829.scala:53: error: not found: value nextState
Error occurred in an application involving default arguments.
copy(agents = updatedAgents, state = nextState, pastHistory = currentHistory)
@@ -33,4 +53,4 @@ t6829.scala:53: error: not found: value currentHistory
Error occurred in an application involving default arguments.
copy(agents = updatedAgents, state = nextState, pastHistory = currentHistory)
^
-9 errors found
+13 errors found
diff --git a/test/files/neg/t7895b.check b/test/files/neg/t7895b.check
new file mode 100644
index 0000000000..87ea72704e
--- /dev/null
+++ b/test/files/neg/t7895b.check
@@ -0,0 +1,7 @@
+t7895b.scala:4: error: not found: value a
+ foo(a, b)
+ ^
+t7895b.scala:4: error: not found: value b
+ foo(a, b)
+ ^
+two errors found
diff --git a/test/files/neg/t7895b.scala b/test/files/neg/t7895b.scala
new file mode 100644
index 0000000000..1603027446
--- /dev/null
+++ b/test/files/neg/t7895b.scala
@@ -0,0 +1,5 @@
+object Test {
+ def foo(a: Any*) = ()
+
+ foo(a, b)
+}
diff --git a/test/files/neg/typeerror.check b/test/files/neg/typeerror.check
index 3ce11dad8a..f117e702f0 100644
--- a/test/files/neg/typeerror.check
+++ b/test/files/neg/typeerror.check
@@ -3,4 +3,9 @@ typeerror.scala:6: error: type mismatch;
required: scala.Long
else add2(x.head, y.head) :: add(x.tail, y.tail)
^
-one error found
+typeerror.scala:6: error: type mismatch;
+ found : Long(in method add)
+ required: scala.Long
+ else add2(x.head, y.head) :: add(x.tail, y.tail)
+ ^
+two errors found