diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 38 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala | 15 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 12 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 7 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 40 | ||||
-rw-r--r-- | src/library/scala/Predef.scala | 4 | ||||
-rw-r--r-- | test/files/neg/bug565.check | 2 | ||||
-rw-r--r-- | test/files/neg/bug800.check | 4 | ||||
-rw-r--r-- | test/files/neg/bug997.check | 4 | ||||
-rw-r--r-- | test/files/run/t0042.check | 1 | ||||
-rwxr-xr-x | test/files/run/t0042.scala | 9 |
11 files changed, 81 insertions, 55 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 { diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 5d450b11e7..9752ea9ed7 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -98,12 +98,12 @@ object Predef { def assume(assumption: Boolean) { if (!assumption) - throw new Error("assumption failed") + throw new java.lang.IllegalArgumentException("assumption failed") } def assume(assumption: Boolean, message: Any) { if (!assumption) - throw new Error("assumption failed: " + message) + throw new java.lang.IllegalArgumentException("assumption failed: " + message) } // tupling ------------------------------------------------------------ diff --git a/test/files/neg/bug565.check b/test/files/neg/bug565.check index 563cff1585..47a1ebd169 100644 --- a/test/files/neg/bug565.check +++ b/test/files/neg/bug565.check @@ -1,5 +1,5 @@ bug565.scala:2: error: only classes can have declared but undefined members (Note that variables need to be initialized to be defined) var s0: String - ^ + ^ one error found diff --git a/test/files/neg/bug800.check b/test/files/neg/bug800.check index b62a3bdde9..00ca02070e 100644 --- a/test/files/neg/bug800.check +++ b/test/files/neg/bug800.check @@ -6,8 +6,8 @@ bug800.scala:8: error: method qualification is defined twice ^ bug800.scala:12: error: value qualification is defined twice var qualification = false; - ^ + ^ bug800.scala:16: error: method qualification is defined twice var qualification = false; - ^ + ^ four errors found diff --git a/test/files/neg/bug997.check b/test/files/neg/bug997.check index 90a1123738..44e383228d 100644 --- a/test/files/neg/bug997.check +++ b/test/files/neg/bug997.check @@ -1,10 +1,10 @@ -bug997.scala:7: error: wrong number of arguments for object Foo of type object Foo +bug997.scala:7: error: wrong number of arguments for object Foo "x" match { case Foo(a) => Console.println(a) } ^ bug997.scala:7: error: not found: value a "x" match { case Foo(a) => Console.println(a) } ^ -bug997.scala:13: error: wrong number of arguments for object Foo of type object Foo +bug997.scala:13: error: wrong number of arguments for object Foo "x" match { case Foo(a, b, c) => Console.println((a,b,c)) } ^ bug997.scala:13: error: not found: value a diff --git a/test/files/run/t0042.check b/test/files/run/t0042.check new file mode 100644 index 0000000000..aeb2d5e239 --- /dev/null +++ b/test/files/run/t0042.check @@ -0,0 +1 @@ +Some(1) diff --git a/test/files/run/t0042.scala b/test/files/run/t0042.scala new file mode 100755 index 0000000000..53314f2885 --- /dev/null +++ b/test/files/run/t0042.scala @@ -0,0 +1,9 @@ +object Test extends Application { + def getClause[T](clauses: List[T]): Option[T] = { + for (c <- clauses) { + return Some(c) + } + return None + } + println(getClause(List(1, 2, 3))) +} |