summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2012-03-26 12:24:05 +0200
committerAdriaan Moors <adriaan.moors@epfl.ch>2012-03-26 17:43:41 +0200
commit9c0442984fff7ea9fa7ded05c619d5c1273d85db (patch)
tree6b1b5a473ae69fb5c083646423f9b7eab9bcbc59 /src
parente0d1f15c244539ce7970c4a903eb49962eaa3569 (diff)
downloadscala-9c0442984fff7ea9fa7ded05c619d5c1273d85db.tar.gz
scala-9c0442984fff7ea9fa7ded05c619d5c1273d85db.tar.bz2
scala-9c0442984fff7ea9fa7ded05c619d5c1273d85db.zip
[vpm] error message on missing parameter type
for selector-less matches that should yield a function
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala25
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala54
2 files changed, 41 insertions, 38 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index e37f5784c9..764823d786 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -376,21 +376,16 @@ trait ContextErrors {
setError(tree)
}
- def MissingParameterTypeError(fun: Tree, vparam: ValDef, pt: Type) = {
- def anonMessage = (
- "\nThe argument types of an anonymous function must be fully known. (SLS 8.5)" +
- "\nExpected type was: " + pt.toLongString
- )
-
- val suffix =
- if (!vparam.mods.isSynthetic) ""
- else " for expanded function" + (fun match {
- case Function(_, Match(_, _)) => anonMessage
- case _ => " " + fun
- })
-
- issueNormalTypeError(vparam, "missing parameter type" + suffix)
- }
+ def MissingParameterTypeError(fun: Tree, vparam: ValDef, pt: Type) =
+ 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")
+
+ def MissingParameterTypeAnonMatchError(vparam: Tree, pt: Type) =
+ issueNormalTypeError(vparam, "missing parameter type for expanded function\n"+
+ "The argument types of an anonymous function must be fully known. (SLS 8.5)\n"+
+ "Expected type was: " + pt.toLongString)
def ConstructorsOrderError(tree: Tree) = {
issueNormalTypeError(tree, "called constructor's definition must precede calling constructor's definition")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 000e5b78eb..06a7311f79 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2176,7 +2176,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def typedMatchAnonFun(tree: Tree, cases: List[CaseDef], mode: Int, pt0: Type, selOverride: Option[(List[ValDef], Tree)] = None) = {
val pt = deskolemizeGADTSkolems(pt0)
val targs = pt.normalize.typeArgs
- val arity = if (isFunctionType(pt)) targs.length - 1 else 1
+ val arity = if (isFunctionType(pt)) targs.length - 1 else 1 // TODO pt should always be a (Partial)Function, right?
val ptRes = if (targs.isEmpty) WildcardType else targs.last // may not be fully defined
val isPartial = pt.typeSymbol == PartialFunctionClass
@@ -2188,6 +2188,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def mkParams(methodSym: Symbol) = {
selOverride match {
+ case None if targs.isEmpty => MissingParameterTypeAnonMatchError(tree, pt); (Nil, EmptyTree)
case None =>
val ps = methodSym newSyntheticValueParams targs.init // is there anything we can do if targs.isEmpty??
val ids = ps map (p => Ident(p.name))
@@ -2213,45 +2214,52 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
anonClass setInfo ClassInfoType(List(ObjectClass.tpe, pt, SerializableClass.tpe), newScope, anonClass)
val methodSym = anonClass.newMethod(nme.apply, tree.pos, FINAL)
val (paramSyms, selector) = mkParams(methodSym)
- methodSym setInfoAndEnter MethodType(paramSyms, AnyClass.tpe)
- val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym)) // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it)
- paramSyms foreach (methodBodyTyper.context.scope enter _)
+ if (selector eq EmptyTree) EmptyTree
+ else {
+ methodSym setInfoAndEnter MethodType(paramSyms, AnyClass.tpe)
+
+ val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym)) // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it)
+ paramSyms foreach (methodBodyTyper.context.scope enter _)
- val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.prepareTranslateMatch(selector, cases, mode, ptRes)
+ val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.prepareTranslateMatch(selector, cases, mode, ptRes)
- val formalTypes = paramSyms map (_.tpe)
- val parents =
- if (isPartial) List(appliedType(AbstractPartialFunctionClass.typeConstructor, List(formalTypes.head, resTp)), SerializableClass.tpe)
- else List(appliedType(AbstractFunctionClass(arity).typeConstructor, formalTypes :+ resTp), SerializableClass.tpe)
+ val formalTypes = paramSyms map (_.tpe)
+ val parents =
+ if (isPartial) List(appliedType(AbstractPartialFunctionClass.typeConstructor, List(formalTypes.head, resTp)), SerializableClass.tpe)
+ else List(appliedType(AbstractFunctionClass(arity).typeConstructor, formalTypes :+ resTp), SerializableClass.tpe)
- anonClass setInfo ClassInfoType(parents, newScope, anonClass)
- methodSym setInfoAndEnter MethodType(paramSyms, resTp)
+ anonClass setInfo ClassInfoType(parents, newScope, anonClass)
+ methodSym setInfoAndEnter MethodType(paramSyms, resTp)
- // use apply's parameter since the scrut's type has been widened
- def missingCase(scrut_ignored: Tree) = (funThis DOT nme.missingCase) (REF(paramSyms.head))
+ // use apply's parameter since the scrut's type has been widened
+ def missingCase(scrut_ignored: Tree) = (funThis DOT nme.missingCase) (REF(paramSyms.head))
- val body = methodBodyTyper.translateMatch(selector1, selectorTp, casesAdapted, resTp, doTranslation, if (isPartial) Some(missingCase) else None)
+ val body = methodBodyTyper.translateMatch(selector1, selectorTp, casesAdapted, resTp, doTranslation, if (isPartial) Some(missingCase) else None)
- DefDef(methodSym, body)
+ DefDef(methodSym, body)
+ }
}
def isDefinedAtMethod = {
val methodSym = anonClass.newMethod(nme._isDefinedAt, tree.pos, FINAL)
val (paramSyms, selector) = mkParams(methodSym)
- val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym)) // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it)
- paramSyms foreach (methodBodyTyper.context.scope enter _)
- methodSym setInfoAndEnter MethodType(paramSyms, BooleanClass.tpe)
+ if (selector eq EmptyTree) EmptyTree
+ else {
+ val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym)) // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it)
+ paramSyms foreach (methodBodyTyper.context.scope enter _)
+ methodSym setInfoAndEnter MethodType(paramSyms, BooleanClass.tpe)
- val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.prepareTranslateMatch(selector, casesTrue, mode, BooleanClass.tpe)
- val body = methodBodyTyper.translateMatch(selector1, selectorTp, casesAdapted, resTp, doTranslation, Some(scrutinee => FALSE_typed))
+ val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.prepareTranslateMatch(selector, casesTrue, mode, BooleanClass.tpe)
+ val body = methodBodyTyper.translateMatch(selector1, selectorTp, casesAdapted, resTp, doTranslation, Some(scrutinee => FALSE_typed))
- DefDef(methodSym, body)
+ DefDef(methodSym, body)
+ }
}
val members = if (!isPartial) List(applyMethod) else List(applyMethod, isDefinedAtMethod)
-
- typed(Block(List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, tree.pos)), New(anonClass.tpe)), mode, pt)
+ if (members.head eq EmptyTree) setError(tree)
+ else typed(Block(List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, tree.pos)), New(anonClass.tpe)), mode, pt)
}
/**