summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-02-14 13:37:19 +0000
committerMartin Odersky <odersky@gmail.com>2007-02-14 13:37:19 +0000
commit979180ca5f30752d94d64b083b6dbca57dab0c4b (patch)
tree5566e84f9803ef46fd9a24fb1e451babec53190c
parente5b3a8a6b49dd4ab333781e3e7ce595ba14b06eb (diff)
downloadscala-979180ca5f30752d94d64b083b6dbca57dab0c4b.tar.gz
scala-979180ca5f30752d94d64b083b6dbca57dab0c4b.tar.bz2
scala-979180ca5f30752d94d64b083b6dbca57dab0c4b.zip
more changes to make tuples (...)
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala22
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala44
-rw-r--r--test/files/neg/bug835.check4
-rw-r--r--test/files/neg/bug876.check2
-rw-r--r--test/files/neg/patmatexhaust.check4
-rw-r--r--test/files/neg/patmatexhaust.scala6
-rw-r--r--test/files/pos/unapplySeq.scala2
-rw-r--r--test/files/run/patmatnew.scala4
-rw-r--r--test/files/run/runtime.scala4
-rw-r--r--test/files/run/tuples.check3
-rw-r--r--test/files/run/tuples.scala28
-rw-r--r--test/files/run/unapply.scala14
15 files changed, 87 insertions, 58 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index f639fc3c44..28a7fd10b0 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -163,10 +163,10 @@ abstract class TreeGen {
def mkNil: Tree =
mkAttributedRef(definitions.NilModule)
- /** Builds a pair */
+ /** Builds a tuple */
def mkTuple(elems: List[Tree]): Tree =
if (elems.isEmpty) Literal(())
- else New(TypeTree(definitions.TupleClass(elems.length).tpe), List(elems))
+ else Apply(mkAttributedRef(definitions.TupleClass(elems.length).caseFactory), elems)
def mkCached(cvar: Symbol, expr: Tree): Tree = {
val cvarRef = if (cvar.owner.isClass) Select(This(cvar.owner), cvar) else Ident(cvar)
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index dfbc330145..18980a9437 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -801,7 +801,7 @@ trait Parsers requires SyntaxAnalyzer {
* | throw Expr
* | return [Expr]
* | [SimpleExpr `.'] Id `=' Expr
- * | SimpleExpr ArgumentExprs `=' Expr
+ * | SimpleExpr1 ArgumentExprs `=' Expr
* | `.' SimpleExpr
* | PostfixExpr [`:' (CompoundType | `_' `*')]
* | PostfixExpr match [`!'] `{' CaseClauses `}'
@@ -1006,21 +1006,20 @@ trait Parsers requires SyntaxAnalyzer {
}
/* SimpleExpr ::= new SimpleType {`(' [Exprs] `)'} {`with' SimpleType} [TemplateBody]
+ * | BlockExpr
* | SimpleExpr1
* SimpleExpr1 ::= literal
* | xLiteral
* | Path
* | StableId `.' class
* | `(' [Expr] `)'
- * | BlockExpr
- * | new Template
* | SimpleExpr `.' Id
* | SimpleExpr TypeArgs
* | SimpleExpr1 ArgumentExprs
*/
def simpleExpr(): Tree = {
var t: Tree = null
- var isNew = false
+ var canApply = true
in.token match {
case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT | STRINGLIT |
SYMBOLLIT | TRUE | FALSE | NULL =>
@@ -1036,6 +1035,7 @@ trait Parsers requires SyntaxAnalyzer {
t = Parens(ts)
case LBRACE =>
t = blockExpr()
+ canApply = false
case NEW =>
t = atPos(in.skipToken()) {
val parents = new ListBuffer[Tree] + simpleType(false)
@@ -1050,7 +1050,7 @@ trait Parsers requires SyntaxAnalyzer {
val stats = if (in.token == LBRACE) templateBody() else List()
makeNew(parents.toList, stats, argss.toList)
}
- isNew = true
+ canApply = false
case _ =>
if (settings.migrate.value) {
if (in.token == MATCH)
@@ -1061,21 +1061,21 @@ trait Parsers requires SyntaxAnalyzer {
syntaxErrorOrIncomplete("illegal start of simple expression", true)
t = errorTermTree
}
- simpleExprRest(t, isNew)
+ simpleExprRest(t, canApply)
}
- def simpleExprRest(t: Tree, isNew: boolean): Tree = in.token match {
+ def simpleExprRest(t: Tree, canApply: boolean): Tree = in.token match {
case DOT =>
- simpleExprRest(atPos(in.skipToken()) { selector(stripParens(t)) }, false)
+ simpleExprRest(atPos(in.skipToken()) { selector(stripParens(t)) }, true)
case LBRACKET =>
t match {
case Ident(_) | Select(_, _) =>
- simpleExprRest(atPos(in.currentPos) { TypeApply(t, typeArgs(false)) }, false)
+ simpleExprRest(atPos(in.currentPos) { TypeApply(t, typeArgs(false)) }, true)
case _ =>
t
}
- case LPAREN | LBRACE if (!isNew) =>
- simpleExprRest(atPos(in.currentPos) { Apply(stripParens(t), argumentExprs()) }, false)
+ case LPAREN | LBRACE if (canApply) =>
+ simpleExprRest(atPos(in.currentPos) { Apply(stripParens(t), argumentExprs()) }, true)
case _ =>
t
}
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 2db48eaa41..5d2e5220d4 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -825,7 +825,7 @@ trait Symbols requires SymbolTable {
* @pre case class is a member of some other class or package
*/
final def caseFactory: Symbol =
- owner.info.decl(name.toTermName).suchThat(.isCaseFactory)
+ initialize.owner.info.decl(name.toTermName).suchThat(.isCaseFactory)
/** If this symbol is a skolem, its corresponding type parameter, otherwise this */
def deSkolemize: Symbol = this
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 91ff898450..52672ed014 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -56,7 +56,7 @@ trait Infer requires Analyzer {
else actuals
def actualArgs(pos: PositionType, actuals: List[Tree], nformals: int): List[Tree] =
- if (nformals == 1 && actuals.length != 1) List(gen.mkTuple(actuals) setPos pos) else actuals
+ if (nformals == 1 && actuals.length != 1) List(atPos(pos)(gen.mkTuple(actuals))) else actuals
/** A fresh type varable with given type parameter as origin.
*
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 1e645f3baa..c05c17a0a2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -545,13 +545,9 @@ trait Typers requires Analyzer {
} else if (!meth.isConstructor && mt.paramTypes.isEmpty) { // (4.3)
adapt(typed(Apply(tree, List()) setPos tree.pos), mode, pt)
} else if (context.implicitsEnabled) {
- if (settings.migrate.value && !meth.isConstructor &&
- isCompatible(tparamsToWildcards(mt, context.undetparams), pt))
- errorTree(tree, migrateMsg + " method can be converted to function only if an expected function type is given");
- else
- errorTree(tree, "missing arguments for "+meth+meth.locationString+
- (if (meth.isConstructor) ""
- else ";\nprefix this method with `&' if you want to treat it as a partially applied function"))
+ errorTree(tree, "missing arguments for "+meth+meth.locationString+
+ (if (meth.isConstructor) ""
+ else ";\nprefix this method with `&' if you want to treat it as a partially applied function"))
} else {
setError(tree)
}
@@ -1382,8 +1378,14 @@ trait Typers requires Analyzer {
case MethodType(formals0, restpe) =>
val formals = formalTypes(formals0, args.length)
var args1 = actualArgs(tree.pos, args, formals.length)
- if (formals.length != args1.length) {
- Console.println(formals+" "+args1);//DEBUG
+ if (args1.length != args.length) {
+ try {
+ silentTypedApply(tree, fun, args1, mode, pt)
+ } catch {
+ case ex: TypeError =>
+ errorTree(tree, "wrong number of arguments for "+treeSymTypeMsg(fun))
+ }
+ } else if (formals.length != args1.length) {
errorTree(tree, "wrong number of arguments for "+treeSymTypeMsg(fun))
} else {
val tparams = context.undetparams
@@ -1537,6 +1539,18 @@ trait Typers requires Analyzer {
}
}
+ def silentTypedApply(tree: Tree, fun: Tree, args: List[Tree], mode: int, pt: Type): Tree =
+ if (context.reportGeneralErrors) {
+ val context1 = context.makeSilent(context.reportAmbiguousErrors)
+ context1.undetparams = context.undetparams
+ val typer1 = newTyper(context1)
+ val result = typer1.typedApply(tree, fun, args, mode, pt)
+ context.undetparams = context1.undetparams
+ result
+ } else {
+ typedApply(tree, fun, args, mode, pt)
+ }
+
def typedAnnotation(constr: Tree, elements: List[Tree]): AttrInfo = {
var attrError: Boolean = false;
def error(pos: PositionType, msg: String): Null = {
@@ -1643,17 +1657,7 @@ trait Typers requires Analyzer {
* @return ...
*/
def tryTypedApply(fun: Tree, args: List[Tree]): Tree = try {
- if (context.reportGeneralErrors) {
- val context1 = context.makeSilent(context.reportAmbiguousErrors)
- context1.undetparams = context.undetparams
- val typer1 = newTyper(context1)
- val result =
- typer1.typedApply(tree, fun, args, mode, pt)
- context.undetparams = context1.undetparams
- result
- } else {
- typedApply(tree, fun, args, mode, pt)
- }
+ silentTypedApply(tree, fun, args, mode, pt)
} catch {
case ex: CyclicReference =>
throw ex
diff --git a/test/files/neg/bug835.check b/test/files/neg/bug835.check
index 16b311ff4c..83db589280 100644
--- a/test/files/neg/bug835.check
+++ b/test/files/neg/bug835.check
@@ -1,4 +1,4 @@
-bug835.scala:2: error: `)' expected
+bug835.scala:2: error: _*-argument may not appear after other arguments matching a *-parameter
Console.println(List(List(1, 2, 3) : _*, List(4, 5, 6) : _*))
- ^
+ ^
one error found
diff --git a/test/files/neg/bug876.check b/test/files/neg/bug876.check
index 54c27fc96a..e7d5d5d78f 100644
--- a/test/files/neg/bug876.check
+++ b/test/files/neg/bug876.check
@@ -1,4 +1,4 @@
-bug876.scala:25: error: wrong number of arguments for method apply: (AssertionError.this.A)manager.B
+bug876.scala:25: error: wrong number of arguments for method apply: (AssertionError.this.A)manager.B in trait Map
assert(manager.map(A2) == List(manager.map(A2, A1)))
^
one error found
diff --git a/test/files/neg/patmatexhaust.check b/test/files/neg/patmatexhaust.check
index 6a0eda5861..19e79b2928 100644
--- a/test/files/neg/patmatexhaust.check
+++ b/test/files/neg/patmatexhaust.check
@@ -5,10 +5,10 @@ patmatexhaust.scala:12: warning: does not cover case {class Bar}
def ma2(x:Foo) = x match {
^
patmatexhaust.scala:24: warning: does not cover case {class Kult}
- case {Kult(_), Qult()} => // Kult missing
+ case (Kult(_), Qult()) => // Kult missing
^
patmatexhaust.scala:26: warning: does not cover case {class Qult}
- case {Qult(), Kult(_)} => // Qult missing
+ case (Qult(), Kult(_)) => // Qult missing
^
patmatexhaust.scala:44: warning: does not cover cases {object Gu,class Gp}
def ma4(x:Deep) = x match { // missing cases: Gu, Gp
diff --git a/test/files/neg/patmatexhaust.scala b/test/files/neg/patmatexhaust.scala
index e1b52a61ef..204bf2f170 100644
--- a/test/files/neg/patmatexhaust.scala
+++ b/test/files/neg/patmatexhaust.scala
@@ -20,10 +20,10 @@ class TestSealedExhaustive { // compile only
def ma33(x:Kult) = x match { // exhaustive
case Kult(_) => // exhaustive
}
- def ma3(x:Mult) = {x,x} match { // not exhaustive
- case Pair(Kult(_), Qult()) => // Kult missing
+ def ma3(x:Mult) = (x,x) match { // not exhaustive
+ case (Kult(_), Qult()) => // Kult missing
//case Pair(Kult(_), Kult(_)) =>
- case Pair(Qult(), Kult(_)) => // Qult missing
+ case (Qult(), Kult(_)) => // Qult missing
//case Pair(Qult(), Qult()) =>
}
diff --git a/test/files/pos/unapplySeq.scala b/test/files/pos/unapplySeq.scala
index aac211de5a..6d13cc8b52 100644
--- a/test/files/pos/unapplySeq.scala
+++ b/test/files/pos/unapplySeq.scala
@@ -2,7 +2,7 @@ object FooSeq {
def unapplySeq(x:Any): Option[Product2[Int,Seq[String]]] = {
if(x.isInstanceOf[Bar]) {
val y = x.asInstanceOf[Bar]
- Some({y.size, y.name})
+ Some(y.size, y.name)
} else None
}
diff --git a/test/files/run/patmatnew.scala b/test/files/run/patmatnew.scala
index e77e10abeb..daa1f9898a 100644
--- a/test/files/run/patmatnew.scala
+++ b/test/files/run/patmatnew.scala
@@ -99,7 +99,7 @@ object Test {
// these are exhaustive matches
// should not generate any warnings
- def f[A](z:{Option[A],Option[A]}) = z match {
+ def f[A](z:(Option[A],Option[A])) = z match {
case Pair(None,Some(x)) => 1
case Pair(Some(x),None ) => 2
case Pair(Some(x),Some(y)) => 3
@@ -118,7 +118,7 @@ object Test {
case _ => true
}
- def h[A](x:{Option[A],Option[A]}) = x match {
+ def h[A](x: (Option[A],Option[A])) = x match {
case Pair(None,_:Some[_]) => 1
case Pair(_:Some[_],None ) => 2
case Pair(_:Some[_],_:Some[_]) => 3
diff --git a/test/files/run/runtime.scala b/test/files/run/runtime.scala
index 192d405eba..45fdf91c95 100644
--- a/test/files/run/runtime.scala
+++ b/test/files/run/runtime.scala
@@ -66,7 +66,7 @@ object Test1Test {
// {System.out.print(12); java.lang}.System.out.println();
// {System.out.print(13); java.lang.System}.out.println();
{Console.print(14); Console}.println;
- {Console.print(15); (() => Console.println):(() => Unit)}();
+ {Console.print(15); (() => Console.println):(() => Unit)} apply ();
{Console.print(16); Console.println};
{Console.print(20)}; test1.bar.System.out.println();
@@ -74,7 +74,7 @@ object Test1Test {
// {System.out.print(22); test1.bar}.System.out.println();
{Console.print(23); test1.bar.System}.out.println();
{Console.print(24); test1.bar.System.out}.println();
- {Console.print(25); test1.bar.System.out.println:(() => Unit)}();
+ {Console.print(25); test1.bar.System.out.println:(() => Unit)} apply ();
{Console.print(26); test1.bar.System.out.println()};
}
diff --git a/test/files/run/tuples.check b/test/files/run/tuples.check
index 731f2746c9..ff7fb4fe7a 100644
--- a/test/files/run/tuples.check
+++ b/test/files/run/tuples.check
@@ -1,2 +1,5 @@
{1,abc,true}
OK
+x = 2; y = xxx; z = 3.14159
+x = 2; y = xxx; z = 3.14159
+x = 2; y = xxx; z = 3.14159
diff --git a/test/files/run/tuples.scala b/test/files/run/tuples.scala
index 3d0dcf7ac0..857b166917 100644
--- a/test/files/run/tuples.scala
+++ b/test/files/run/tuples.scala
@@ -1,8 +1,30 @@
+import Function._
+
object Test extends Application {
- var xyz: Triple(int, String, boolean) = _
- xyz = Triple(1, "abc", true)
+ var xyz: (int, String, boolean) = _
+ xyz = (1, "abc", true)
Console.println(xyz)
xyz match {
- case Triple(1, "abc", true) => Console.println("OK")
+ case (1, "abc", true) => Console.println("OK")
}
+ def func(x : int, y : String, z : double) : unit = {
+ Console.println("x = " + x + "; y = " + y + "; z = " + z);
+ }
+
+ def params = (2, "xxx", 3.14159) // (*****)
+
+ tupled(&func)(params) // call the function with all the params at once
+ func(2, "xxx", 3.14159) // the same call
+ (&func).apply(2, "xxx", 3.14159) // the same call
+
+ // Composing a tuple
+ def t = (1, "Hello", false)
+
+ // Decomposing a tuple
+ val (i, s, b) = t
+
+ // all the assertions are passed
+ assert(i == 1)
+ assert(s == "Hello")
+ assert(b == false)
}
diff --git a/test/files/run/unapply.scala b/test/files/run/unapply.scala
index 8b913ee593..fb154cf192 100644
--- a/test/files/run/unapply.scala
+++ b/test/files/run/unapply.scala
@@ -34,7 +34,7 @@ object Foo extends Assert {
case _ => None
}
def doMatch1(b:Bar) = b match {
- case Foo(s:Int, n:String) => {s,n}
+ case Foo(s:Int, n:String) => (s,n)
}
def doMatch2(b:Bar) = b match {
case Fii() => null
@@ -50,7 +50,7 @@ object Foo extends Assert {
}
def run {
val b = new Bar
- assertEquals(doMatch1(b),{50,"medium"})
+ assertEquals(doMatch1(b),(50,"medium"))
assertEquals(doMatch2(b),null)
assertEquals(doMatch3(b),"medium")
assertEquals(doMatch4(b),"medium")
@@ -73,16 +73,16 @@ object Mas extends Assert {
def run {
val b = new Baz
assertEquals(b match {
- case Gaz(s:Int, n:String) => {s,n}
- }, {60,"too large"})
+ case Gaz(s:Int, n:String) => (s,n)
+ }, (60,"too large"))
}
}
object LisSeqArr extends Assert {
def run {
- assertEquals((List(1,2,3): Any) match { case List(x,y,_*) => {x,y}}, {1,2})
- assertEquals((List(1,2,3): Any) match { case Seq(x,y,_*) => {x,y}}, {1,2})
- assertEquals((Array(1,2,3): Any) match { case Seq(x,y,_*) => {x,y}}, {1,2})
+ assertEquals((List(1,2,3): Any) match { case List(x,y,_*) => (x,y)}, (1,2))
+ assertEquals((List(1,2,3): Any) match { case Seq(x,y,_*) => (x,y)}, (1,2))
+ assertEquals((Array(1,2,3): Any) match { case Seq(x,y,_*) => (x,y)}, (1,2))
//assertEquals((Array(1,2,3): Any) match { case Array(x,y,_*) => {x,y}}, {1,2})
}
}