diff options
author | Paul Phillips <paulp@improving.org> | 2012-09-12 16:54:49 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-09-12 20:47:39 -0700 |
commit | f5e71796d5b964026f5723318d29be5b189b442e (patch) | |
tree | 39926b10b22d920555244622655b27c104cc37ee | |
parent | 5f674e44c5d3dccb55ce080c60d92b8e412d03ac (diff) | |
download | scala-f5e71796d5b964026f5723318d29be5b189b442e.tar.gz scala-f5e71796d5b964026f5723318d29be5b189b442e.tar.bz2 scala-f5e71796d5b964026f5723318d29be5b189b442e.zip |
Better error message for pattern arity errors.
Because friends don't tell friends:
"wrong number of arguments for <none>"
8 files changed, 38 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index ae1a2c7e8e..37e452dc6a 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -959,7 +959,7 @@ abstract class Erasure extends AddInterfaces case TypeApply(sel @ Select(qual, name), List(targ)) => if (qual.tpe != null && isPrimitiveValueClass(qual.tpe.typeSymbol) && targ.tpe != null && targ.tpe <:< AnyRefClass.tpe) unit.error(sel.pos, "isInstanceOf cannot test if value types are references.") - + def mkIsInstanceOf(q: () => Tree)(tp: Type): Tree = Apply( TypeApply( diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 5097ecc3fe..86cdc59303 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -1474,13 +1474,13 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case Select(qual, name) => def transformSelect = { qual match { - case _: Super if illegalSpecializedInheritance(currentClass) => + case _: Super if illegalSpecializedInheritance(currentClass) => val pos = tree.pos debuglog(pos.source.file.name+":"+pos.line+": not specializing call to super inside illegal specialized inheritance class.") debuglog(pos.lineContent) tree case _ => - + debuglog("specializing Select %s [tree.tpe: %s]".format(symbol.defString, tree.tpe)) //log("!!! select " + tree + " -> " + symbol.info + " specTypeVars: " + specializedTypeVars(symbol.info)) diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index b7195b0349..49ace019b9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -470,9 +470,6 @@ trait ContextErrors { def NamedAndDefaultArgumentsNotSupportedForMacros(tree: Tree, fun: Tree) = NormalTypeError(tree, "macros application do not support named and/or default arguments") - def WrongNumberOfArgsError(tree: Tree, fun: Tree) = - NormalTypeError(tree, "wrong number of arguments for "+ treeSymTypeMsg(fun)) - def TooManyArgsNamesDefaultsError(tree: Tree, fun: Tree) = NormalTypeError(tree, "too many arguments for "+treeSymTypeMsg(fun)) @@ -512,8 +509,8 @@ trait ContextErrors { def TooManyArgsPatternError(fun: Tree) = NormalTypeError(fun, "too many arguments for unapply pattern, maximum = "+definitions.MaxTupleArity) - def WrongNumberArgsPatternError(tree: Tree, fun: Tree) = - NormalTypeError(tree, "wrong number of arguments for "+treeSymTypeMsg(fun)) + def WrongNumberOfArgsError(tree: Tree, fun: Tree) = + NormalTypeError(tree, "wrong number of arguments for "+ treeSymTypeMsg(fun)) def ApplyWithoutArgsError(tree: Tree, fun: Tree) = NormalTypeError(tree, fun.tpe+" does not take parameters") diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index f8a5c401df..e5c0f5767c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -59,6 +59,19 @@ trait TypeDiagnostics { * the map, the addendum should also be printed. */ private var addendums = perRunCaches.newMap[Position, () => String]() + private var isTyperInPattern = false + + /** Devising new ways of communicating error info out of + * desperation to work on error messages. This is used + * by typedPattern to wrap its business so we can generate + * a sensible error message when things go south. + */ + def typingInPattern[T](body: => T): T = { + val saved = isTyperInPattern + isTyperInPattern = true + try body + finally isTyperInPattern = saved + } def setAddendum(pos: Position, msg: () => String) = if (pos != NoPosition) @@ -138,13 +151,17 @@ trait TypeDiagnostics { def hasParams = tree.tpe.paramSectionCount > 0 def preResultString = if (hasParams) ": " else " of type " - def nullMessage = "expression of type " + tree.tpe - def overloadedMessage = "overloaded method " + sym + " with alternatives:\n" + alternativesString(tree) + def patternMessage = "pattern " + tree.tpe.finalResultType + valueParamsString(tree.tpe) + def exprMessage = "expression of type " + tree.tpe + def overloadedMessage = s"overloaded method $sym with alternatives:\n" + alternativesString(tree) def moduleMessage = "" + sym def defaultMessage = moduleMessage + preResultString + tree.tpe def applyMessage = defaultMessage + tree.symbol.locationString - if (sym == null) nullMessage + if ((sym eq null) || (sym eq NoSymbol)) { + if (isTyperInPattern) patternMessage + else exprMessage + } else if (sym.isOverloaded) overloadedMessage else if (sym.isModule) moduleMessage else if (sym.name == nme.apply) applyMessage diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index d90141b732..73ccdeec2c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3237,7 +3237,7 @@ trait Typers extends Modes with Adaptations with Tags { val nbSubPats = args.length val (formals, formalsExpanded) = extractorFormalTypes(resTp, nbSubPats, fun1.symbol) - if (formals == null) duplErrorTree(WrongNumberArgsPatternError(tree, fun)) + if (formals == null) duplErrorTree(WrongNumberOfArgsError(tree, fun)) else { val args1 = typedArgs(args, mode, formals, formalsExpanded) // This used to be the following (failing) assert: @@ -5452,7 +5452,7 @@ trait Typers extends Modes with Adaptations with Tags { // as a compromise, context.enrichmentEnabled tells adaptToMember to go ahead and enrich, // but arbitrary conversions (in adapt) are disabled // TODO: can we achieve the pattern matching bit of the string interpolation SIP without this? - context.withImplicitsDisabledAllowEnrichment(typed(tree, PATTERNmode, pt)) + typingInPattern(context.withImplicitsDisabledAllowEnrichment(typed(tree, PATTERNmode, pt))) } /** Types a (fully parameterized) type tree */ diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check index 2809350855..f3c45a6aa0 100644 --- a/test/files/neg/names-defaults-neg.check +++ b/test/files/neg/names-defaults-neg.check @@ -76,7 +76,7 @@ and method f in object t8 of type (a: Int, b: Object)String match argument types (a: Int,b: String) and expected result type Any println(t8.f(a = 0, b = "1")) // ambigous reference ^ -names-defaults-neg.scala:69: error: wrong number of arguments for <none>: (x: Int, y: String)A1 +names-defaults-neg.scala:69: error: wrong number of arguments for pattern A1(x: Int,y: String) A1() match { case A1(_) => () } ^ names-defaults-neg.scala:76: error: no type parameters for method test4: (x: T[T[List[T[X forSome { type X }]]]])T[T[List[T[X forSome { type X }]]]] exist so that it can be applied to arguments (List[Int]) diff --git a/test/files/neg/wrong-args-for-none.check b/test/files/neg/wrong-args-for-none.check new file mode 100644 index 0000000000..d3b2d572ab --- /dev/null +++ b/test/files/neg/wrong-args-for-none.check @@ -0,0 +1,4 @@ +wrong-args-for-none.scala:5: error: wrong number of arguments for pattern Test.Foo(x: Int,y: Int) + def f(x: Any) = x match { case Bar(Foo(5)) => } + ^ +one error found diff --git a/test/files/neg/wrong-args-for-none.scala b/test/files/neg/wrong-args-for-none.scala new file mode 100644 index 0000000000..1caa4782a3 --- /dev/null +++ b/test/files/neg/wrong-args-for-none.scala @@ -0,0 +1,6 @@ +object Test { + case class Foo(x: Int, y: Int) + case class Bar(x: AnyRef) + + def f(x: Any) = x match { case Bar(Foo(5)) => } +} |