From 35775a8fc87e9f3538e13e8d26f9b151138efe8c Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 17 Aug 2013 08:57:53 -0700 Subject: SI-4425 do some validity checking on unapplies. Filter out unapplies which can't be called (such as those with a second non-implicit parameter list) and report the error in a meaningful fashion. --- src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 7 ++++++- src/compiler/scala/tools/nsc/typechecker/Unapplies.scala | 10 ++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 81f5545695..7f4bf0dfbc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -593,7 +593,12 @@ trait ContextErrors { } def CaseClassConstructorError(tree: Tree) = { - issueNormalTypeError(tree, tree.symbol + " is not a case class constructor, nor does it have an unapply/unapplySeq method") + val baseMessage = tree.symbol + " is not a case class constructor, nor does it have an unapply/unapplySeq method" + val addendum = directUnapplyMember(tree.symbol.info) match { + case sym if hasMultipleNonImplicitParamLists(sym) => s"\nNote: ${sym.defString} exists in ${tree.symbol}, but it cannot be used as an extractor due to its second non-implicit parameter list" + case _ => "" + } + issueNormalTypeError(tree, baseMessage + addendum) setError(tree) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala index 0e2c836860..18b8f8a9ce 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala @@ -46,8 +46,14 @@ trait Unapplies extends ast.TreeDSL { } } - /** returns unapply or unapplySeq if available */ - def unapplyMember(tp: Type): Symbol = (tp member nme.unapply) orElse (tp member nme.unapplySeq) + /** Returns unapply or unapplySeq if available, without further checks. + */ + def directUnapplyMember(tp: Type): Symbol = (tp member nme.unapply) orElse (tp member nme.unapplySeq) + + /** Filters out unapplies with multiple (non-implicit) parameter lists, + * as they cannot be used as extractors + */ + def unapplyMember(tp: Type): Symbol = directUnapplyMember(tp) filter (sym => !hasMultipleNonImplicitParamLists(sym)) object ExtractorType { def unapply(tp: Type): Option[Symbol] = unapplyMember(tp).toOption -- cgit v1.2.3