Skip to content

Commit 7e4a97e

Browse files
committed
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.
1 parent d0af55c commit 7e4a97e

File tree

10 files changed

+101
-25
lines changed

10 files changed

+101
-25
lines changed

src/compiler/scala/tools/nsc/typechecker/Contexts.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ trait Contexts { self: Analyzer =>
329329

330330
/** The first error, if any, in the report buffer */
331331
def firstError: Option[AbsTypeError] = reportBuffer.firstError
332+
def errors: Seq[AbsTypeError] = reportBuffer.errors
332333
/** Does the report buffer contain any errors? */
333334
def hasErrors = reportBuffer.hasErrors
334335

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,19 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
7979
case SilentResultValue(value) if !p(value) => SilentTypeError(TypeErrorWrapper(new TypeError(NoPosition, "!p")))
8080
case _ => this
8181
}
82-
@inline final def orElse[T1 >: T](f: AbsTypeError => T1): T1 = this match {
82+
@inline final def orElse[T1 >: T](f: Seq[AbsTypeError] => T1): T1 = this match {
8383
case SilentResultValue(value) => value
84-
case SilentTypeError(err) => f(err)
84+
case s : SilentTypeError => f(s.errors)
8585
}
8686
}
87-
case class SilentTypeError(err: AbsTypeError) extends SilentResult[Nothing] { }
87+
class SilentTypeError private(val errors: Seq[AbsTypeError]) extends SilentResult[Nothing] {
88+
def err: AbsTypeError = errors.head
89+
}
90+
object SilentTypeError {
91+
def apply(errors: AbsTypeError*): SilentTypeError = new SilentTypeError(errors)
92+
def unapply(error: SilentTypeError): Option[AbsTypeError] = error.errors.headOption
93+
}
94+
8895
case class SilentResultValue[+T](value: T) extends SilentResult[T] { }
8996

9097
def newTyper(context: Context): Typer = new NormalTyper(context)
@@ -682,14 +689,13 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
682689
context.undetparams = context1.undetparams
683690
context.savedTypeBounds = context1.savedTypeBounds
684691
context.namedApplyBlockInfo = context1.namedApplyBlockInfo
685-
context1.firstError match {
686-
case Some(err) =>
687-
stopStats()
688-
SilentTypeError(err)
689-
case None =>
690-
// If we have a successful result, emit any warnings it created.
691-
context1.flushAndIssueWarnings()
692-
SilentResultValue(result)
692+
if (context1.hasErrors) {
693+
stopStats()
694+
SilentTypeError(context1.errors: _*)
695+
} else {
696+
// If we have a successful result, emit any warnings it created.
697+
context1.flushAndIssueWarnings()
698+
SilentResultValue(result)
693699
}
694700
} else {
695701
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
12581264
reportError
12591265
}
12601266

1261-
silent(_.adaptToMember(qual, HasMember(name), reportAmbiguous = false)) orElse (err =>
1267+
silent(_.adaptToMember(qual, HasMember(name), reportAmbiguous = false)) orElse (errs =>
12621268
onError {
1263-
if (reportAmbiguous) context issue err
1269+
if (reportAmbiguous) errs foreach (context issue _)
12641270
setError(tree)
12651271
}
12661272
)
@@ -3786,7 +3792,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
37863792
}
37873793
}
37883794
}
3789-
def wrapErrors(tree: Tree, typeTree: Typer => Tree): Tree = silent(typeTree) orElse (err => DynamicRewriteError(tree, err))
3795+
def wrapErrors(tree: Tree, typeTree: Typer => Tree): Tree = silent(typeTree) orElse (err => DynamicRewriteError(tree, err.head))
37903796
}
37913797

37923798
def typed1(tree: Tree, mode: Mode, pt: Type): Tree = {
@@ -4173,7 +4179,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
41734179
def tryTypedApply(fun: Tree, args: List[Tree]): Tree = {
41744180
val start = if (Statistics.canEnable) Statistics.startTimer(failedApplyNanos) else null
41754181

4176-
def onError(typeError: AbsTypeError): Tree = {
4182+
def onError(typeErrors: Seq[AbsTypeError]): Tree = {
41774183
if (Statistics.canEnable) Statistics.stopTimer(failedApplyNanos, start)
41784184

41794185
// 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
41984204
case TypeApply(fun, args) => treesInResult(fun) ++ args.flatMap(treesInResult)
41994205
case _ => Nil
42004206
})
4201-
def errorInResult(tree: Tree) = treesInResult(tree) exists (_.pos == typeError.errPos)
4207+
def errorInResult(tree: Tree) = treesInResult(tree) exists (err => typeErrors.exists(_.errPos == err.pos))
42024208

4203-
val retry = (typeError.errPos != null) && (fun :: tree :: args exists errorInResult)
4209+
val retry = (typeErrors.forall(_.errPos != null)) && (fun :: tree :: args exists errorInResult)
42044210
typingStack.printTyping({
42054211
val funStr = ptTree(fun) + " and " + (args map ptTree mkString ", ")
42064212
if (retry) "second try: " + funStr
4207-
else "no second try: " + funStr + " because error not in result: " + typeError.errPos+"!="+tree.pos
4213+
else "no second try: " + funStr + " because error not in result: " + typeErrors.head.errPos+"!="+tree.pos
42084214
})
42094215
if (retry) {
42104216
val Select(qual, name) = fun
@@ -4220,7 +4226,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
42204226
case _ => ()
42214227
}
42224228
}
4223-
issue(typeError)
4229+
typeErrors foreach issue
42244230
setError(treeCopy.Apply(tree, fun, args))
42254231
}
42264232

test/files/neg/names-defaults-neg.check

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ names-defaults-neg.scala:5: error: type mismatch;
77
required: Int
88
test1(b = 2, a = "#")
99
^
10+
names-defaults-neg.scala:5: error: type mismatch;
11+
found : Int(2)
12+
required: String
13+
test1(b = 2, a = "#")
14+
^
1015
names-defaults-neg.scala:8: error: positional after named argument.
1116
test1(b = "(*", 23)
1217
^
@@ -122,6 +127,12 @@ names-defaults-neg.scala:131: error: reference to var2 is ambiguous; it is both
122127
names-defaults-neg.scala:134: error: missing parameter type for expanded function ((x$1) => a = x$1)
123128
val taf2: Int => Unit = testAnnFun(a = _, b = get("+"))
124129
^
130+
names-defaults-neg.scala:134: error: not found: value a
131+
val taf2: Int => Unit = testAnnFun(a = _, b = get("+"))
132+
^
133+
names-defaults-neg.scala:134: error: not found: value get
134+
val taf2: Int => Unit = testAnnFun(a = _, b = get("+"))
135+
^
125136
names-defaults-neg.scala:135: error: parameter 'a' is already specified at parameter position 1
126137
val taf3 = testAnnFun(b = _: String, a = get(8))
127138
^
@@ -131,6 +142,9 @@ names-defaults-neg.scala:136: error: missing parameter type for expanded functio
131142
names-defaults-neg.scala:136: error: missing parameter type for expanded function ((x$4) => b = x$4)
132143
val taf4: (Int, String) => Unit = testAnnFun(_, b = _)
133144
^
145+
names-defaults-neg.scala:136: error: not found: value b
146+
val taf4: (Int, String) => Unit = testAnnFun(_, b = _)
147+
^
134148
names-defaults-neg.scala:144: error: variable definition needs type because 'x' is used as a named argument in its body.
135149
def t3 { var x = t.f(x = 1) }
136150
^
@@ -168,4 +182,4 @@ names-defaults-neg.scala:180: error: reference to x is ambiguous; it is both a m
168182
class u18 { var x: Int = u.f(x = 1) }
169183
^
170184
four warnings found
171-
42 errors found
185+
46 errors found

test/files/neg/t4515.check

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,14 @@ t4515.scala:37: error: type mismatch;
33
required: _$2
44
handler.onEvent(target, ctx.getEvent, node, ctx)
55
^
6-
one error found
6+
t4515.scala:37: error: type mismatch;
7+
found : Main.DerivedPushNode[_$1] where type _$1
8+
required: Main.PushNode[_$2]
9+
handler.onEvent(target, ctx.getEvent, node, ctx)
10+
^
11+
t4515.scala:37: error: type mismatch;
12+
found : Main.PushEventContext[_$1] where type _$1
13+
required: Main.PushEventContext[_$2]
14+
handler.onEvent(target, ctx.getEvent, node, ctx)
15+
^
16+
three errors found

test/files/neg/t556.check

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
t556.scala:3: error: missing parameter type
22
def g:Int = f((x,y)=>x)
33
^
4-
one error found
4+
t556.scala:3: error: missing parameter type
5+
def g:Int = f((x,y)=>x)
6+
^
7+
two errors found

test/files/neg/t5572.check

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@ t5572.scala:16: error: type mismatch;
33
required: A
44
Z.transf(a, b) match {
55
^
6+
t5572.scala:16: error: type mismatch;
7+
found : A
8+
required: B
9+
Z.transf(a, b) match {
10+
^
611
t5572.scala:18: error: type mismatch;
712
found : A
813
required: B
914
run(sth, b)
1015
^
11-
two errors found
16+
three errors found

test/files/neg/t6829.check

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,31 @@ t6829.scala:50: error: type mismatch;
2020
required: _53.State where val _53: G
2121
val r = rewards(agent).r(s,a,s2)
2222
^
23+
t6829.scala:50: error: type mismatch;
24+
found : a.type (with underlying type T2)
25+
required: _53.Action where val _53: G
26+
val r = rewards(agent).r(s,a,s2)
27+
^
28+
t6829.scala:50: error: type mismatch;
29+
found : s2.type (with underlying type T3)
30+
required: _53.State where val _53: G
31+
val r = rewards(agent).r(s,a,s2)
32+
^
2333
t6829.scala:51: error: type mismatch;
2434
found : s.type (with underlying type T1)
2535
required: _50.State
2636
agent.learn(s,a,s2,r): G#Agent
2737
^
38+
t6829.scala:51: error: type mismatch;
39+
found : a.type (with underlying type T2)
40+
required: _50.Action
41+
agent.learn(s,a,s2,r): G#Agent
42+
^
43+
t6829.scala:51: error: type mismatch;
44+
found : s2.type (with underlying type T3)
45+
required: _50.State
46+
agent.learn(s,a,s2,r): G#Agent
47+
^
2848
t6829.scala:53: error: not found: value nextState
2949
Error occurred in an application involving default arguments.
3050
copy(agents = updatedAgents, state = nextState, pastHistory = currentHistory)
@@ -33,4 +53,4 @@ t6829.scala:53: error: not found: value currentHistory
3353
Error occurred in an application involving default arguments.
3454
copy(agents = updatedAgents, state = nextState, pastHistory = currentHistory)
3555
^
36-
9 errors found
56+
13 errors found

test/files/neg/t7895b.check

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
t7895b.scala:4: error: not found: value a
2+
foo(a, b)
3+
^
4+
t7895b.scala:4: error: not found: value b
5+
foo(a, b)
6+
^
7+
two errors found

test/files/neg/t7895b.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
def foo(a: Any*) = ()
3+
4+
foo(a, b)
5+
}

test/files/neg/typeerror.check

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,9 @@ typeerror.scala:6: error: type mismatch;
33
required: scala.Long
44
else add2(x.head, y.head) :: add(x.tail, y.tail)
55
^
6-
one error found
6+
typeerror.scala:6: error: type mismatch;
7+
found : Long(in method add)
8+
required: scala.Long
9+
else add2(x.head, y.head) :: add(x.tail, y.tail)
10+
^
11+
two errors found

0 commit comments

Comments
 (0)