summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-07-02 01:01:44 +0000
committerPaul Phillips <paulp@improving.org>2010-07-02 01:01:44 +0000
commit57b7e442af26e07dc2411f46b0a8103dfe054101 (patch)
treefa27f49579d3e2a62781af86f148eb1d4f33fcce /src/compiler
parent9421f2ecaf85cb2e409e73dad7554e466303c284 (diff)
downloadscala-57b7e442af26e07dc2411f46b0a8103dfe054101.tar.gz
scala-57b7e442af26e07dc2411f46b0a8103dfe054101.tar.bz2
scala-57b7e442af26e07dc2411f46b0a8103dfe054101.zip
Fail more gracefully on > 22 case class paramet...
Fail more gracefully on > 22 case class parameters. Closes #3631, no review.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeInfo.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala7
3 files changed, 19 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
index f21b1b20ff..46ddf7b24b 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
@@ -151,6 +151,12 @@ abstract class TreeInfo {
case _ :: stats1 => firstConstructor(stats1)
}
+ /** The arguments to the first constructor in `stats'. */
+ def firstConstructorArgs(stats: List[Tree]): List[Tree] = firstConstructor(stats) match {
+ case DefDef(_, _, _, args :: _, _, _) => args
+ case _ => Nil
+ }
+
/** The value definitions marked PRESUPER in this statement sequence */
def preSuperFields(stats: List[Tree]): List[ValDef] =
for (vdef @ ValDef(mods, _, _, _) <- stats if mods hasFlag PRESUPER) yield vdef
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index d56b8ed944..2123a00550 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -287,13 +287,11 @@ trait Namers { self: Analyzer =>
* class definition tree.
* @return the companion object symbol.
*/
- def ensureCompanionObject(tree: ClassDef, creator: => Tree): Symbol = {
- val m: Symbol = context.scope.lookup(tree.name.toTermName).filter(! _.isSourceMethod)
- if (m.isModule && inCurrentScope(m) && currentRun.compiles(m)) m
- else
- /*util.trace("enter synthetic companion object for "+currentRun.compiles(m)+":")*/(
- enterSyntheticSym(creator))
- }
+ def ensureCompanionObject(tree: ClassDef, creator: => Tree): Symbol = {
+ val m: Symbol = context.scope.lookup(tree.name.toTermName).filter(! _.isSourceMethod)
+ if (m.isModule && inCurrentScope(m) && currentRun.compiles(m)) m
+ else enterSyntheticSym(creator)
+ }
private def enterSymFinishWith(tree: Tree, tparams: List[TypeDef]) {
val sym = tree.symbol
@@ -350,6 +348,9 @@ trait Namers { self: Analyzer =>
tree.symbol = enterClassSymbol(tree)
finishWith(tparams)
if (mods.isCase) {
+ if (treeInfo.firstConstructorArgs(impl.body).size > MaxFunctionArity)
+ context.error(tree.pos, "Implementation restriction: case classes cannot have more than " + MaxFunctionArity + " parameters.")
+
val m = ensureCompanionObject(tree, caseModuleDef(tree))
caseClassOfModuleClass(m.moduleClass) = tree
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index c3631f0d05..735cb4a3c4 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -133,8 +133,11 @@ trait Unapplies extends ast.TreeDSL
/** The module corresponding to a case class; overrides toString to show the module's name
*/
def caseModuleDef(cdef: ClassDef): ModuleDef = {
- def inheritFromFun = !(cdef.mods hasFlag ABSTRACT) && cdef.tparams.isEmpty && constrParamss(cdef).length == 1
- def createFun = gen.scalaFunctionConstr(constrParamss(cdef).head map (_.tpt), toIdent(cdef), abstractFun = true)
+ // > MaxFunctionArity is caught in Namers, but for nice error reporting instead of
+ // an abrupt crash we trim the list here.
+ def primaries = constrParamss(cdef).head take MaxFunctionArity map (_.tpt)
+ def inheritFromFun = !cdef.mods.isAbstract && cdef.tparams.isEmpty && constrParamss(cdef).length == 1
+ def createFun = gen.scalaFunctionConstr(primaries, toIdent(cdef), abstractFun = true)
def parents = if (inheritFromFun) List(createFun) else Nil
def toString = DefDef(
Modifiers(OVERRIDE | FINAL),