Skip to content
This repository was archived by the owner on Sep 1, 2020. It is now read-only.

Commit 2d2fe0c

Browse files
author
Adriaan Moors
committed
Merge pull request scala#578 from lrytz/wip/t5044-squashed
fix SI-5044: better error message on cyclic error and named/default args
2 parents 423db24 + 4669ac1 commit 2d2fe0c

File tree

5 files changed

+38
-3
lines changed

5 files changed

+38
-3
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,12 @@ trait ContextErrors {
10341034
setError(arg)
10351035
} else arg
10361036
}
1037+
1038+
def WarnAfterNonSilentRecursiveInference(param: Symbol, arg: Tree)(implicit context: Context) = {
1039+
val note = "type-checking the invocation of "+ param.owner +" checks if the named argument expression '"+ param.name + " = ...' is a valid assignment\n"+
1040+
"in the current scope. The resulting type inference error (see above) can be fixed by providing an explicit type in the local definition for "+ param.name +"."
1041+
context.warning(arg.pos, note)
1042+
}
10371043

10381044
def UnknownParameterNameNamesDefaultError(arg: Tree, name: Name)(implicit context: Context) = {
10391045
issueNormalTypeError(arg, "unknown parameter name: " + name)

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,14 @@ trait NamesDefaults { self: Analyzer =>
478478
// instead of arg, but can't do that because eventually setType(ErrorType)
479479
// is called, and EmptyTree can only be typed NoType. Thus we need to
480480
// disable conforms as a view...
481-
try typer.silent(_.typed(arg, subst(paramtpe))) match {
481+
val errsBefore = reporter.ERROR.count
482+
try typer.silent { tpr =>
483+
val res = tpr.typed(arg, subst(paramtpe))
484+
// better warning for SI-5044: if `silent` was not actually silent give a hint to the user
485+
if (errsBefore < reporter.ERROR.count)
486+
WarnAfterNonSilentRecursiveInference(param, arg)(context)
487+
res
488+
} match {
482489
case SilentResultValue(t) => !t.isErroneous // #4041
483490
case _ => false
484491
}
@@ -487,7 +494,7 @@ trait NamesDefaults { self: Analyzer =>
487494
// CyclicReferences. Fix for #3685
488495
case cr @ CyclicReference(sym, _) =>
489496
(sym.name == param.name) && sym.accessedOrSelf.isVariable && {
490-
NameClashError(sym, arg)(typer.context)
497+
NameClashError(sym, arg)(context)
491498
true
492499
}
493500
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,12 @@ names-defaults-neg.scala:170: error: reference to x is ambiguous; it is both a m
149149
names-defaults-neg.scala:177: error: variable definition needs type because 'x' is used as a named argument in its body.
150150
class u15 { var x = u.f(x = 1) }
151151
^
152+
names-defaults-neg.scala:177: warning: type-checking the invocation of method f checks if the named argument expression 'x = ...' is a valid assignment
153+
in the current scope. The resulting type inference error (see above) can be fixed by providing an explicit type in the local definition for x.
154+
class u15 { var x = u.f(x = 1) }
155+
^
152156
names-defaults-neg.scala:180: error: reference to x is ambiguous; it is both a method parameter and a variable in scope.
153157
class u18 { var x: Int = u.f(x = 1) }
154158
^
155-
one warning found
159+
two warnings found
156160
41 errors found

test/files/neg/t5044.check

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
t5044.scala:7: error: recursive value a needs type
2+
val id = m(a)
3+
^
4+
t5044.scala:6: warning: type-checking the invocation of method foo checks if the named argument expression 'id = ...' is a valid assignment
5+
in the current scope. The resulting type inference error (see above) can be fixed by providing an explicit type in the local definition for id.
6+
val a = foo(id = 1)
7+
^
8+
one warning found
9+
one error found

test/files/neg/t5044.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class T {
2+
def foo[T](id: T) = 0
3+
def m(a: Int) = 0
4+
5+
def f {
6+
val a = foo(id = 1)
7+
val id = m(a)
8+
}
9+
}

0 commit comments

Comments
 (0)