summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-10-30 18:20:03 +0000
committerMartin Odersky <odersky@gmail.com>2006-10-30 18:20:03 +0000
commit247577e9664407de2f98294a2adae6f8131d919d (patch)
tree60ee5425bcf3dbd375558a3b38581c622158e28d /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parent7ebc41cda22ee26d4242e305782a14f7e6bf63aa (diff)
downloadscala-247577e9664407de2f98294a2adae6f8131d919d.tar.gz
scala-247577e9664407de2f98294a2adae6f8131d919d.tar.bz2
scala-247577e9664407de2f98294a2adae6f8131d919d.zip
fixed bug421
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala47
1 files changed, 36 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 3e3193f964..6b76f71b6f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -111,6 +111,11 @@ trait Typers requires Analyzer {
*/
val CONSTmode = 0x800
+ /** The mode <code>REGPATmode</code> is set when regular expression patterns
+ * are allowed.
+ */
+ val REGPATmode = 0x1000
+
class Typer(context0: Context) {
import context0.unit
@@ -254,6 +259,12 @@ trait Typers requires Analyzer {
case _ =>
}
+ def checkRegPatOK(pos: PositionType, mode: int): unit =
+ if ((mode & REGPATmode) == 0) {
+ error(pos, "no regular expression pattern allowed here\n"+
+ "(regular expression patterns are only allowed in arguments to *-parameters)")
+ }
+
/** Check that type of given tree does not contain local or private
* components.
*/
@@ -1191,14 +1202,28 @@ trait Typers requires Analyzer {
checkNoDoubleDefs(List.mapConserve(stats)(typedStat))
}
- def typedArg(arg: Tree, mode: int, pt: Type): Tree = {
+ def typedArg(arg: Tree, mode: int, newmode: int, pt: Type): Tree = {
val argTyper = if ((mode & SCCmode) != 0) newTyper(context.makeConstructorContext)
else this
- argTyper.typed(arg, mode & (stickyModes | POLYmode), pt)
+ argTyper.typed(arg, mode & stickyModes | newmode, pt)
}
def typedArgs(args: List[Tree], mode: int) =
- List.mapConserve(args)(arg => typedArg(arg, mode, WildcardType))
+ List.mapConserve(args)(arg => typedArg(arg, mode, 0, WildcardType))
+
+ def typedArgs(args: List[Tree], mode: int, originalFormals: List[Type], adaptedFormals: List[Type]) =
+ if ((mode & PATTERNmode) != 0 && isVarArgs(originalFormals)) {
+ val nonVarCount = originalFormals.length - 1
+ val prefix =
+ List.map2(args take nonVarCount, adaptedFormals take nonVarCount) ((arg, formal) =>
+ typedArg(arg, mode, 0, formal))
+ val suffix =
+ List.map2(args drop nonVarCount, adaptedFormals drop nonVarCount) ((arg, formal) =>
+ typedArg(arg, mode, REGPATmode, formal))
+ prefix ::: suffix
+ } else {
+ List.map2(args, adaptedFormals)((arg, formal) => typedArg(arg, mode, 0, formal))
+ }
def typedApply(tree: Tree, fun0: Tree, args: List[Tree], mode: int, pt: Type): Tree = {
var fun = fun0;
@@ -1224,8 +1249,7 @@ trait Typers requires Analyzer {
val tparams = context.undetparams
context.undetparams = List()
if (tparams.isEmpty) {
- val args1 = List.map2(args, formals)((arg, formal) =>
- typedArg(arg, mode, formal))
+ val args1 = typedArgs(args, mode, formals0, formals)
def ifPatternSkipFormals(tp: Type) = tp match {
case MethodType(_, rtp) if ((mode & PATTERNmode) != 0) => rtp
case _ => tp
@@ -1253,7 +1277,7 @@ trait Typers requires Analyzer {
if (targ == WildcardType) tparam.tpe else targ)
def typedArgToPoly(arg: Tree, formal: Type): Tree = {
val lenientPt = formal.subst(tparams, lenientTargs)
- val arg1 = typedArg(arg, mode | POLYmode, lenientPt)
+ val arg1 = typedArg(arg, mode, POLYmode, lenientPt)
val argtparams = context.undetparams
context.undetparams = List()
if (!argtparams.isEmpty) {
@@ -1316,11 +1340,10 @@ trait Typers requires Analyzer {
val fun1 = typed(atPos(fun.pos) { Apply(Select(Ident(fun.symbol), unapp), List(arg)) }, EXPRmode, funPt)
if (fun1.tpe.isErroneous) setError(tree)
else {
- var argPts = if(unapp.name == nme.unapply) optionOfProductElems(fun1.tpe)
- else unapplySeqResultToMethodSig(fun1.tpe)
- argPts = formalTypes(argPts, args.length)
-
- val args1 = List.map2(args, argPts)((arg, formal) => typedArg(arg, mode, formal))
+ var formals0 = if(unapp.name == nme.unapply) optionOfProductElems(fun1.tpe)
+ else unapplySeqResultToMethodSig(fun1.tpe)
+ val formals1 = formalTypes(formals0, args.length)
+ val args1 = typedArgs(args, mode, formals0, formals1)
UnApply(fun1, args1) setPos tree.pos setType pt
}
/* --- end unapply --- */
@@ -1736,6 +1759,7 @@ trait Typers requires Analyzer {
.typedBlock(tree, mode, pt)
case Sequence(elems) =>
+ checkRegPatOK(tree.pos, mode)
val elems1 = List.mapConserve(elems)(elem => typed(elem, mode, pt))
copy.Sequence(tree, elems1) setType pt
@@ -1744,6 +1768,7 @@ trait Typers requires Analyzer {
copy.Alternative(tree, alts1) setType pt
case Star(elem) =>
+ checkRegPatOK(tree.pos, mode)
val elem1 = typed(elem, mode, pt)
copy.Star(tree, elem1) setType pt