summaryrefslogtreecommitdiff
path: root/src/compiler/scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-09-10 13:12:27 +0000
committerMartin Odersky <odersky@gmail.com>2007-09-10 13:12:27 +0000
commitb907c8eb599b53d83b2494e63a928182ec97f2eb (patch)
tree525ad28a003906f9c493595f84e5ec4a977cfc88 /src/compiler/scala
parentc9e92bfc89083227aa18f88b07688afd625970af (diff)
downloadscala-b907c8eb599b53d83b2494e63a928182ec97f2eb.tar.gz
scala-b907c8eb599b53d83b2494e63a928182ec97f2eb.tar.bz2
scala-b907c8eb599b53d83b2494e63a928182ec97f2eb.zip
1. added var pattern = expr syntax
2. better error messages in two situations 3. fixed tickets 5, 33, 42 4. changed check files of 3 failing tests
Diffstat (limited to 'src/compiler/scala')
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala38
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala15
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala40
5 files changed, 64 insertions, 48 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 04e83a5ebe..a820c985e6 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1941,7 +1941,7 @@ trait Parsers {
case VAL =>
patDefOrDcl(mods)
case VAR =>
- varDefOrDcl(mods)
+ patDefOrDcl(mods | Flags.MUTABLE)
case DEF =>
List(funDefOrDcl(mods))
case TYPE =>
@@ -1955,18 +1955,29 @@ trait Parsers {
/** PatDef ::= Pattern2 {`,' Pattern2} [`:' Type] `=' Expr
* ValDcl ::= Id {`,' Id} `:' Type
+ * VarDef ::= PatDef | Id {`,' Id} `:' Type `=' `_'
*/
def patDefOrDcl(mods: Modifiers): List[Tree] = {
var newmods = mods
- var lhs = new ListBuffer[Tree]
+ val lhsBuf = new ListBuffer[Tree]
do {
inNextToken
- lhs += stripParens(pattern2(false))
+ val p = pattern2(false)
+ lhsBuf += stripParens(p)
} while (inToken == COMMA)
+ val lhs = lhsBuf.toList
val tp = typedOpt()
val rhs =
- if (tp.isEmpty || inToken == EQUALS) equalsExpr()
- else {
+ if (tp.isEmpty || inToken == EQUALS) {
+ accept(EQUALS)
+ if (!tp.isEmpty && newmods.hasFlag(Flags.MUTABLE) &&
+ (lhs.toList forall (_.isInstanceOf[Ident])) && inToken == USCORE) {
+ inNextToken
+ EmptyTree
+ } else {
+ expr()
+ }
+ } else {
newmods = newmods | Flags.DEFERRED
EmptyTree
}
@@ -1979,10 +1990,11 @@ trait Parsers {
else
Typed(p, tp),
rhs.duplicate) map atPos(p.pos)
- if (rhs == EmptyTree) {
+ if (newmods.hasFlag(Flags.DEFERRED)) {
trees match {
case List(ValDef(_, _, _, EmptyTree)) =>
- if (mods.hasFlag(Flags.LAZY)) syntaxError(p.pos, "lazy values may not be abstract", false)
+ if (mods.hasFlag(Flags.LAZY))
+ syntaxError(p.pos, "lazy values may not be abstract", false)
case _ => syntaxError(p.pos, "pattern definition may not be abstract", false)
}
}
@@ -1991,7 +2003,7 @@ trait Parsers {
for (p <- lhs.toList; d <- mkDefs(p)) yield d
}
- /** VarDef ::= Id {`,' Id} [`:' Type] `=' Expr
+ /** VarDef ::= PatDef
* | Id {`,' Id} `:' Type `=' `_'
* VarDcl ::= Id {`,' Id} `:' Type
*/
@@ -2389,7 +2401,7 @@ trait Parsers {
/** BlockStatSeq ::= { BlockStat semi } [ResultExpr]
* BlockStat ::= Import
* | Annotations [implicit] [lazy] Def
- * | LocalModifiers TmplDef
+ * | Annotations LocalModifiers TmplDef
* | Expr1
* |
*/
@@ -2412,13 +2424,9 @@ trait Parsers {
} else if (isExprIntro) {
stats += expr(InBlock)
if (inToken != RBRACE && inToken != CASE) acceptStatSep()
- } else if (isDefIntro) {
- localDef(NoMods)
- } else if (isLocalModifier || inToken == AT) {
+ } else if (isDefIntro || isLocalModifier || in.token == AT) {
val annots = annotations()
- localDef(modifiers() withAnnotations annots)
- } else if (!isStatSep) {
- localDef(localModifiers())
+ localDef(localModifiers() withAnnotations annots)
} else if (isStatSep) {
inNextToken
} else {
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index 0a202dfffa..0ba8c78e5d 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -398,16 +398,16 @@ abstract class TreeBuilder {
case None =>
// in case there are no variables in pattern
- // val p = e ==> e.match (case p => ())
+ // val/var p = e ==> e.match (case p => ())
//
- // in case there is exactly one variable in pattern
- // val x_1 = e.match (case p => (x_1))
+ // in case there is exactly one variable x_1 in pattern
+ // val/var p = e ==> val/var x_1 = e.match (case p => (x_1))
//
// in case there are more variables in pattern
- // val p = e ==> private synthetic val t$ = e.match (case p => (x_1, ..., x_N))
- // val x_1 = t$._1
+ // val/var p = e ==> private synthetic val t$ = e.match (case p => (x_1, ..., x_N))
+ // val/var x_1 = t$._1
// ...
- // val x_N = t$._N
+ // val/var x_N = t$._N
val pat1 = patvarTransformer.transform(pat)
val vars = getVariables(pat1)
val matchExpr = atPos(pat1.pos){
@@ -422,7 +422,8 @@ abstract class TreeBuilder {
List(ValDef(mods, vname, tpt, matchExpr))
case _ =>
val tmp = freshName(pat1.pos)
- val firstDef = ValDef(Modifiers(PRIVATE | LOCAL | SYNTHETIC | (mods.flags & LAZY)), tmp, TypeTree(), matchExpr)
+ val firstDef = ValDef(Modifiers(PRIVATE | LOCAL | SYNTHETIC | (mods.flags & LAZY)),
+ tmp, TypeTree(), matchExpr)
var cnt = 0
val restDefs = for (val (vname, tpt) <- vars) yield {
cnt = cnt + 1
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 96ded10df1..5427debfd0 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -134,11 +134,9 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
// ------- Handling non-local returns -------------------------------------------------
- /** The type of a non-local return expression for given method */
- private def nonLocalReturnExceptionType(meth: Symbol) =
- appliedType(
- NonLocalReturnExceptionClass.typeConstructor,
- List(meth.tpe.finalResultType))
+ /** The type of a non-local return expression with given argument type */
+ private def nonLocalReturnExceptionType(argtype: Type) =
+ appliedType(NonLocalReturnExceptionClass.typeConstructor, List(argtype))
/** A hashmap from method symbols to non-local return keys */
private val nonLocalReturnKeys = new HashMap[Symbol, Symbol]
@@ -162,7 +160,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
localTyper.typed {
Throw(
New(
- TypeTree(nonLocalReturnExceptionType(meth)),
+ TypeTree(nonLocalReturnExceptionType(expr.tpe)),
List(List(Ident(nonLocalReturnKey(meth)), expr))))
}
@@ -181,7 +179,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
*/
private def nonLocalReturnTry(body: Tree, key: Symbol, meth: Symbol) = {
localTyper.typed {
- val extpe = nonLocalReturnExceptionType(meth)
+ val extpe = nonLocalReturnExceptionType(meth.tpe.finalResultType)
val ex = meth.newValue(body.pos, nme.ex) setInfo extpe
val pat = Bind(ex,
Typed(Ident(nme.WILDCARD),
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index beaa2ac5af..b79fca75f9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -194,8 +194,9 @@ trait Infer {
"overloaded method " + tree.symbol + " with alternatives " + tree.tpe
else
tree.symbol.toString() +
- (if (tree.tpe.paramSectionCount > 0) ": " else " of type ") +
- tree.tpe +
+ (if (tree.symbol.isModule) ""
+ else if (tree.tpe.paramSectionCount > 0) ": "+tree.tpe
+ else " of type "+tree.tpe) +
(if (tree.symbol.name == nme.apply) tree.symbol.locationString else "")
def applyErrorMsg(tree: Tree, msg: String, argtpes: List[Type], pt: Type) = (
@@ -812,6 +813,8 @@ trait Infer {
widen(tp.normalize)
case rtp @ RefinedType(parents, decls) =>
copyRefinedType(rtp, List.mapConserve(parents)(widen), decls)
+ case AnnotatedType(_, underlying) =>
+ widen(underlying)
case _ =>
tp
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 27fc934ef6..cd852c8b50 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1329,7 +1329,6 @@ trait Typers { self: Analyzer =>
*/
def typedCase(cdef: CaseDef, pattpe: Type, pt: Type): CaseDef = {
val pat1: Tree = typedPattern(cdef.pat, pattpe)
- //Console.println("UNAPPLY3:"+pat1+":"+pat1.tpe)
val guard1: Tree = if (cdef.guard == EmptyTree) EmptyTree
else typed(cdef.guard, BooleanClass.tpe)
var body1: Tree = typed(cdef.body, pt)
@@ -1665,27 +1664,25 @@ trait Typers { self: Analyzer =>
//todo: replace arg with arg.asInstanceOf[inferTypedPattern(unappFormal, arg.tpe)] instead.
argDummy.setInfo(arg.tpe) // bq: this line fixed #1281. w.r.t. comment ^^^, maybe good enough?
}
- val funPrefix = if (fun.symbol.owner.isMethod) NoPrefix else fun.tpe.prefix match {
+/*
+ val funPrefix = fun.tpe.prefix match {
case tt @ ThisType(sym) =>
- //Console.println("tt = "+tt+" sym.isModuleClass = "+sym.isModuleClass+" sym.isPackageClass = "+sym.isPackageClass+" isStaticModul="+sym.isStaticModule+" fso = "+fun.symbol.owner+" fso.isClass"+fun.symbol.owner.isClass)
- if((sym eq fun.symbol.owner)|| !sym.isPackageClass) {
- //Console.println("1 ThisType("+sym+")")
- tt
- } else {
+ //Console.println(" sym="+sym+" "+" .isPackageClass="+sym.isPackageClass+" .isModuleClass="+sym.isModuleClass);
+ //Console.println(" funsymown="+fun.symbol.owner+" .isClass+"+fun.symbol.owner.isClass);
+ //Console.println(" contains?"+sym.tpe.decls.lookup(fun.symbol.name));
+ if(sym != fun.symbol.owner && (sym.isPackageClass||sym.isModuleClass) /*(1)*/ ) { // (1) see 'files/pos/unapplyVal.scala'
+ if(fun.symbol.owner.isClass) {
+ mkThisType(fun.symbol.owner)
+ } else {
//Console.println("2 ThisType("+fun.symbol.owner+")")
- mkThisType(fun.symbol.owner) // see 'files/pos/unapplyVal.scala'
- }
- //if (sym.isPackageClass && fun.symbol.owner.isClass) { // (1)
- //mkThisType(fun.symbol.owner)
- //} else {
- // Console.println("NoPrefix")
- // NoPrefix // see 'files/run/unapplyComplex.scala'
- // }
- case st @ SingleType(pre, sym) =>
+ NoPrefix // see 'files/run/unapplyComplex.scala'
+ }
+ } else tt
+ case st @ SingleType(pre, sym) => st
st
case xx => xx // cannot happen?
}
- val fun1untyped = atPos(fun.pos) {
+ val fun1untyped = fun
Apply(
Select(
gen.mkAttributedRef(funPrefix, fun.symbol) setType null,
@@ -1693,6 +1690,15 @@ trait Typers { self: Analyzer =>
unapp),
List(arg))
}
+*/
+ val fun1untyped = atPos(fun.pos) {
+ Apply(
+ Select(
+ fun setType null, // setType null is necessary so that ref will be stabilized; see bug 881
+ unapp),
+ List(arg))
+ }
+
val fun1 = typed(fun1untyped)
if (fun1.tpe.isErroneous) setError(tree)
else {