summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala23
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala16
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala4
3 files changed, 39 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 7ecc2be9be..2472f63993 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -408,11 +408,28 @@ trait ContextErrors {
setError(tree)
}
- def MissingParameterTypeError(fun: Tree, vparam: ValDef, pt: Type) =
+ def MissingParameterTypeError(fun: Tree, vparam: ValDef, pt: Type, withTupleAddendum: Boolean) = {
+ def issue(what: String) = {
+ val addendum: String = fun match {
+ case Function(params, _) if withTupleAddendum =>
+ val funArity = params.length
+ val example = analyzer.exampleTuplePattern(params map (_.name))
+ (pt baseType FunctionClass(1)) match {
+ case TypeRef(_, _, arg :: _) if arg.typeSymbol == TupleClass(funArity) && funArity > 1 =>
+ sm"""|
+ |Note: The expected type requires a one-argument function accepting a $funArity-Tuple.
+ | Consider a pattern matching anoynmous function, `{ case $example => ... }`"""
+ case _ => ""
+ }
+ case _ => ""
+ }
+ issueNormalTypeError(vparam, what + addendum)
+ }
if (vparam.mods.isSynthetic) fun match {
case Function(_, Match(_, _)) => MissingParameterTypeAnonMatchError(vparam, pt)
- case _ => issueNormalTypeError(vparam, "missing parameter type for expanded function " + fun)
- } else issueNormalTypeError(vparam, "missing parameter type")
+ case _ => issue("missing parameter type for expanded function " + fun)
+ } else issue("missing parameter type")
+ }
def MissingParameterTypeAnonMatchError(vparam: Tree, pt: Type) =
issueNormalTypeError(vparam, "missing parameter type for expanded function\n"+
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 695a1e2e24..b801b644fb 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -109,6 +109,22 @@ trait TypeDiagnostics {
case x => x.toString
}
+ /**
+ * [a, b, c] => "(a, b, c)"
+ * [a, B] => "(param1, param2)"
+ * [a, B, c] => "(param1, ..., param2)"
+ */
+ final def exampleTuplePattern(names: List[Name]): String = {
+ val arity = names.length
+ val varPatterNames: Option[List[String]] = sequence(names map {
+ case name if nme.isVariableName(name) => Some(name.decode)
+ case _ => None
+ })
+ def parenthesize(a: String) = s"($a)"
+ def genericParams = (Seq("param1") ++ (if (arity > 2) Seq("...") else Nil) ++ Seq(s"param$arity"))
+ parenthesize(varPatterNames.getOrElse(genericParams).mkString(", "))
+ }
+
def alternatives(tree: Tree): List[Type] = tree.tpe match {
case OverloadedType(pre, alternatives) => alternatives map pre.memberType
case _ => Nil
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 6d799b0098..4973346eff 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2906,6 +2906,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
else if (argpts.lengthCompare(numVparams) != 0)
WrongNumberOfParametersError(fun, argpts)
else {
+ var issuedMissingParameterTypeError = false
foreach2(fun.vparams, argpts) { (vparam, argpt) =>
if (vparam.tpt.isEmpty) {
vparam.tpt.tpe =
@@ -2923,7 +2924,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
case _ =>
}
- MissingParameterTypeError(fun, vparam, pt)
+ MissingParameterTypeError(fun, vparam, pt, withTupleAddendum = !issuedMissingParameterTypeError)
+ issuedMissingParameterTypeError = true
ErrorType
}
if (!vparam.tpt.pos.isDefined) vparam.tpt setPos vparam.pos.focus