Skip to content

Commit

Permalink
better feedback for SI-5044
Browse files Browse the repository at this point in the history
  • Loading branch information
lrytz committed May 18, 2012
1 parent b48aa90 commit 4669ac1
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 3 deletions.
6 changes: 6 additions & 0 deletions src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
Expand Up @@ -1034,6 +1034,12 @@ trait ContextErrors {
setError(arg) setError(arg)
} else arg } else arg
} }

def WarnAfterNonSilentRecursiveInference(param: Symbol, arg: Tree)(implicit context: Context) = {
val note = "type-checking the invocation of "+ param.owner +" checks if the named argument expression '"+ param.name + " = ...' is a valid assignment\n"+
"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 +"."
context.warning(arg.pos, note)
}


def UnknownParameterNameNamesDefaultError(arg: Tree, name: Name)(implicit context: Context) = { def UnknownParameterNameNamesDefaultError(arg: Tree, name: Name)(implicit context: Context) = {
issueNormalTypeError(arg, "unknown parameter name: " + name) issueNormalTypeError(arg, "unknown parameter name: " + name)
Expand Down
11 changes: 9 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
Expand Up @@ -478,7 +478,14 @@ trait NamesDefaults { self: Analyzer =>
// instead of arg, but can't do that because eventually setType(ErrorType) // instead of arg, but can't do that because eventually setType(ErrorType)
// is called, and EmptyTree can only be typed NoType. Thus we need to // is called, and EmptyTree can only be typed NoType. Thus we need to
// disable conforms as a view... // disable conforms as a view...
try typer.silent(_.typed(arg, subst(paramtpe))) match { val errsBefore = reporter.ERROR.count
try typer.silent { tpr =>
val res = tpr.typed(arg, subst(paramtpe))
// better warning for SI-5044: if `silent` was not actually silent give a hint to the user
if (errsBefore < reporter.ERROR.count)
WarnAfterNonSilentRecursiveInference(param, arg)(context)
res
} match {
case SilentResultValue(t) => !t.isErroneous // #4041 case SilentResultValue(t) => !t.isErroneous // #4041
case _ => false case _ => false
} }
Expand All @@ -487,7 +494,7 @@ trait NamesDefaults { self: Analyzer =>
// CyclicReferences. Fix for #3685 // CyclicReferences. Fix for #3685
case cr @ CyclicReference(sym, _) => case cr @ CyclicReference(sym, _) =>
(sym.name == param.name) && sym.accessedOrSelf.isVariable && { (sym.name == param.name) && sym.accessedOrSelf.isVariable && {
NameClashError(sym, arg)(typer.context) NameClashError(sym, arg)(context)
true true
} }
} }
Expand Down
6 changes: 5 additions & 1 deletion test/files/neg/names-defaults-neg.check
Expand Up @@ -149,8 +149,12 @@ names-defaults-neg.scala:170: error: reference to x is ambiguous; it is both a m
names-defaults-neg.scala:177: error: variable definition needs type because 'x' is used as a named argument in its body. names-defaults-neg.scala:177: error: variable definition needs type because 'x' is used as a named argument in its body.
class u15 { var x = u.f(x = 1) } class u15 { var x = u.f(x = 1) }
^ ^
names-defaults-neg.scala:177: warning: type-checking the invocation of method f checks if the named argument expression 'x = ...' is a valid assignment
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.
class u15 { var x = u.f(x = 1) }
^
names-defaults-neg.scala:180: error: reference to x is ambiguous; it is both a method parameter and a variable in scope. names-defaults-neg.scala:180: error: reference to x is ambiguous; it is both a method parameter and a variable in scope.
class u18 { var x: Int = u.f(x = 1) } class u18 { var x: Int = u.f(x = 1) }
^ ^
one warning found two warnings found
41 errors found 41 errors found
9 changes: 9 additions & 0 deletions test/files/neg/t5044.check
@@ -0,0 +1,9 @@
t5044.scala:7: error: recursive value a needs type
val id = m(a)
^
t5044.scala:6: warning: type-checking the invocation of method foo checks if the named argument expression 'id = ...' is a valid assignment
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.
val a = foo(id = 1)
^
one warning found
one error found
9 changes: 9 additions & 0 deletions test/files/neg/t5044.scala
@@ -0,0 +1,9 @@
class T {
def foo[T](id: T) = 0
def m(a: Int) = 0

def f {
val a = foo(id = 1)
val id = m(a)
}
}

1 comment on commit 4669ac1

@retronym
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lrytz https://issues.scala-lang.org/browse/SI-5091 doesn't trigger this error yet.

Please sign in to comment.