summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-03-10 11:55:36 +0000
committerMartin Odersky <odersky@gmail.com>2003-03-10 11:55:36 +0000
commitd5da7d9aa5a8d4833775454853e81ead20cc37a7 (patch)
treed48297de81cb6c84853b94ae02b6edabee5bce5f
parent1fb5a195b5575e7015be4fd1ee8f89116a78cfb5 (diff)
downloadscala-d5da7d9aa5a8d4833775454853e81ead20cc37a7.tar.gz
scala-d5da7d9aa5a8d4833775454853e81ead20cc37a7.tar.bz2
scala-d5da7d9aa5a8d4833775454853e81ead20cc37a7.zip
*** empty log message ***
-rw-r--r--config/list/library.lst6
-rw-r--r--sources/examples/ComputeServer.scala32
-rw-r--r--sources/examples/boundedbuffer.scala30
-rw-r--r--sources/examples/futures.scala12
-rw-r--r--sources/scala/LinkedList.scala13
-rw-r--r--sources/scala/Monitor.scala14
-rw-r--r--sources/scala/NativeMonitor.java14
-rw-r--r--sources/scala/Predef.scala89
-rw-r--r--sources/scala/concurrent/Channel.scala21
-rw-r--r--sources/scala/concurrent/Lock.scala14
-rw-r--r--sources/scala/concurrent/SyncChannel.scala26
-rw-r--r--sources/scala/concurrent/SyncVar.scala19
-rw-r--r--sources/scala/concurrent/TIMEOUT.scala3
-rw-r--r--sources/scala/concurrent/ops.scala39
-rw-r--r--sources/scalac/transformer/UnCurry.java23
-rw-r--r--sources/scalac/typechecker/Analyzer.java78
-rw-r--r--sources/scalac/typechecker/Infer.java11
17 files changed, 341 insertions, 103 deletions
diff --git a/config/list/library.lst b/config/list/library.lst
index 760ed5473e..e2dab12b5a 100644
--- a/config/list/library.lst
+++ b/config/list/library.lst
@@ -6,15 +6,16 @@
$colon$colon.scala
BufferedIterator.scala
Cell.scala
-ConsStreamClass.scala
-EmptyStream.scala
Iterator.scala
Labelled.scala
+LinkedList.scala
List.scala
Monitor.scala
Nil.scala
None.scala
Option.scala
+Ord.scala
+PartialFunction.scala
Predef.scala
Seq.scala
Some.scala
@@ -29,6 +30,5 @@ Tuple6.scala
Tuple7.scala
Tuple8.scala
Tuple9.scala
-PartialFunction.scala
##############################################################################
diff --git a/sources/examples/ComputeServer.scala b/sources/examples/ComputeServer.scala
new file mode 100644
index 0000000000..e322860b78
--- /dev/null
+++ b/sources/examples/ComputeServer.scala
@@ -0,0 +1,32 @@
+package examples;
+
+import concurrent._, concurrent.ops._;
+
+class ComputeServer(n: Int) {
+ private trait Job {
+ type t;
+ def task: t;
+ def return(x: t): Unit;
+ }
+
+ private val openJobs = new Channel[Job]();
+
+ private def processor(i: Int): Unit {
+ while (True) {
+ val job = openJobs.read;
+ job.return(job.task)
+ }
+ }
+ def future[a](def p: a): () => a {
+ val reply = new SyncVar[a]();
+ openJobs.write{
+ new Job with {
+ type t = a;
+ def task = p;
+ def return(x: a) = reply.set(x);
+ }
+ }
+ () => reply.get
+ }
+ replicate(1,n){processor}
+}
diff --git a/sources/examples/boundedbuffer.scala b/sources/examples/boundedbuffer.scala
new file mode 100644
index 0000000000..f308d0d472
--- /dev/null
+++ b/sources/examples/boundedbuffer.scala
@@ -0,0 +1,30 @@
+package examples;
+
+import concurrent.ops._;
+
+class BoundedBuffer[a](N: Int) extends Monitor() with {
+ var in = 0, out = 0, n = 0;
+ val elems = new Array[a](N);
+
+ def put(x: a) = synchronized {
+ await (n < N);
+ elems(in) = x ; in = (in + 1) % N ; n = n + 1;
+ if (n == 1) notifyAll();
+ }
+
+ def get: a = synchronized {
+ await (n != 0);
+ val x = elems(out) ; out = (out + 1) % N ; n = n - 1;
+ if (n == N - 1) notifyAll();
+ x
+ }
+}
+
+module test {
+ val buf = new BoundedBuffer[String](10);
+ var cnt = 0;
+ def produceString = { cnt = cnt + 1; cnt.toString() }
+ def consumeString(ss: String) = System.out.println(ss);
+ spawn { while (True) { val ssss = produceString ; buf.put(ssss) } }
+ spawn { while (True) { val s = buf.get ; consumeString(s) } }
+} \ No newline at end of file
diff --git a/sources/examples/futures.scala b/sources/examples/futures.scala
new file mode 100644
index 0000000000..1e218351af
--- /dev/null
+++ b/sources/examples/futures.scala
@@ -0,0 +1,12 @@
+package examples;
+import concurrent.ops._;
+module futures {
+ def someLengthyComputation = 1;
+ def anotherLengthyComputation = 2;
+ def f(x: Int) = x + x;
+ def g(x: Int) = x * x;
+ val x = future(someLengthyComputation);
+ anotherLengthyComputation;
+ val y = f(x()) + g(x());
+ System.out.println(y);
+} \ No newline at end of file
diff --git a/sources/scala/LinkedList.scala b/sources/scala/LinkedList.scala
new file mode 100644
index 0000000000..e2a71c979e
--- /dev/null
+++ b/sources/scala/LinkedList.scala
@@ -0,0 +1,13 @@
+package scala;
+
+class LinkedList[a]() {
+ var elem: a = _;
+ var next: LinkedList[a] = null;
+ def append(x: a): LinkedList[a] = {
+ val l = new LinkedList();
+ l.elem = x;
+ this.next = l;
+ l
+ }
+}
+
diff --git a/sources/scala/Monitor.scala b/sources/scala/Monitor.scala
index cf7d6d4144..927f323986 100644
--- a/sources/scala/Monitor.scala
+++ b/sources/scala/Monitor.scala
@@ -1,15 +1,9 @@
-package scala with {
+package scala;
- class Monitor extends NativeMonitor() with {
+class Monitor() extends NativeMonitor() with {
- def synchronized[a](def p: a): a = {
- var value: Ref[a] = null;
- synchronised(=> value = Ref(p));
- value.elem
- }
+ def synchronized[a](def p: a): a = synchronised(p);
- def await(def cond: Boolean) = while (!cond) { this.wait() }
-
- }
+ def await(def cond: Boolean) = while (!cond) { this.wait() }
}
diff --git a/sources/scala/NativeMonitor.java b/sources/scala/NativeMonitor.java
new file mode 100644
index 0000000000..25fca6b98a
--- /dev/null
+++ b/sources/scala/NativeMonitor.java
@@ -0,0 +1,14 @@
+package scala;
+
+public class NativeMonitor {
+
+ /** @meta method [?A] (def ?A) ?A;
+ */
+ public java.lang.Object synchronised(scala.Function0 p) {
+ java.lang.Object result;
+ synchronized(this) {
+ result = p.apply();
+ }
+ return result;
+ }
+}
diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala
index cdd2eee20f..56cd07ed60 100644
--- a/sources/scala/Predef.scala
+++ b/sources/scala/Predef.scala
@@ -1,61 +1,62 @@
-package scala {
+package scala;
- module Predef {
+module Predef {
- val True = Boolean.True;
- val False = Boolean.False;
+ val True = Boolean.True;
+ val False = Boolean.False;
- val List = scala.List;
+ val List = scala.List;
- def List[a](x: a*): List[a] = {
- def mkList(elems: Iterator[a]): List[a] =
- if (elems.hasNext) elems.next :: mkList(elems)
- else Nil();
- mkList(x.elements);
- }
-
- def error[err](x: String):err = new java.lang.RuntimeException(x).throw;
+ def List[a](x: a*): List[a] = {
+ def mkList(elems: Iterator[a]): List[a] =
+ if (elems.hasNext) elems.next :: mkList(elems)
+ else Nil();
+ mkList(x.elements);
+ }
- def try[a](def block: a): Except[a] =
- new Except(scala.runtime.ResultOrException.tryBlock(block));
+ def error[err](x: String):err = new java.lang.RuntimeException(x).throw;
- def range(lo: Int, hi: Int): List[Int] =
- if (lo > hi) List() else lo :: range(lo + 1, hi);
+ def try[a](def block: a): Except[a] =
+ new Except(scala.runtime.ResultOrException.tryBlock(block));
- def while(def condition: Boolean)(def command: Unit): Unit =
- if (condition) {
- command; while(condition)(command)
- } else {
- }
+ def range(lo: Int, hi: Int): List[Int] =
+ if (lo > hi) List() else lo :: range(lo + 1, hi);
- trait Until {
- def until(def condition: Boolean): Unit
+ def while(def condition: Boolean)(def command: Unit): Unit =
+ if (condition) {
+ command; while(condition)(command)
+ } else {
}
- def repeat(def command: Unit): Until =
- new Until {
- def until(def condition: Boolean): Unit = {
- command ;
- if (condition) {}
- else until(condition)
- }
+ trait Until {
+ def until(def condition: Boolean): Unit
+ }
+
+ def repeat(def command: Unit): Until =
+ new Until {
+ def until(def condition: Boolean): Unit = {
+ command ;
+ if (condition) {}
+ else until(condition)
}
+ }
- type Pair = Tuple2;
- def Pair[a, b](x: a, y: b) = Tuple2(x, y);
+ type Pair = Tuple2;
+ def Pair[a, b](x: a, y: b) = Tuple2(x, y);
- type Triple = Tuple3;
- def Triple[a, b, c](x: a, y: b, z: c) = Tuple3(x, y, z);
- }
+ type Triple = Tuple3;
+ def Triple[a, b, c](x: a, y: b, z: c) = Tuple3(x, y, z);
+}
- class Except[a](r: scala.runtime.ResultOrException[a]) {
- def except(handler: PartialFunction[Throwable, a]): a =
- if (r.exc == null) r.result
- else if (handler isDefinedAt r.exc) handler(r.exc)
- else r.exc.throw;
- def finally(def handler: Unit): a =
- if (r.exc == null) r.result else { handler; r.exc.throw }
- }
+class Except[a](r: scala.runtime.ResultOrException[a]) {
+ def except(handler: PartialFunction[Throwable, a]): a =
+ if (r.exc == null) r.result as a
+ else if (handler isDefinedAt r.exc) handler(r.exc)
+ else r.exc.throw;
+ def finally(def handler: Unit): a =
+ if (r.exc == null) r.result as a else { handler; r.exc.throw }
}
+
+
diff --git a/sources/scala/concurrent/Channel.scala b/sources/scala/concurrent/Channel.scala
new file mode 100644
index 0000000000..b58cf15862
--- /dev/null
+++ b/sources/scala/concurrent/Channel.scala
@@ -0,0 +1,21 @@
+package scala.concurrent;
+
+class Channel[a]() extends Monitor() {
+ private var written: LinkedList[a] = new LinkedList();
+ private var lastWritten = written;
+ private var nreaders = 0;
+
+ def write(x: a) = synchronized {
+ lastWritten.next = new LinkedList();
+ lastWritten = lastWritten.next;
+ if (nreaders > 0) notify();
+ }
+
+ def read: a = synchronized {
+ if (written.next == null) {
+ nreaders = nreaders + 1; wait(); nreaders = nreaders - 1;
+ }
+ written = written.next;
+ written.elem;
+ }
+}
diff --git a/sources/scala/concurrent/Lock.scala b/sources/scala/concurrent/Lock.scala
new file mode 100644
index 0000000000..87d677085c
--- /dev/null
+++ b/sources/scala/concurrent/Lock.scala
@@ -0,0 +1,14 @@
+package scala.concurrent;
+
+class Lock() extends Monitor() {
+ var available = True;
+ def acquire = {
+ if (!available) wait();
+ available = False
+ }
+ def release = {
+ available = True;
+ notify()
+ }
+}
+
diff --git a/sources/scala/concurrent/SyncChannel.scala b/sources/scala/concurrent/SyncChannel.scala
new file mode 100644
index 0000000000..5aec23da1f
--- /dev/null
+++ b/sources/scala/concurrent/SyncChannel.scala
@@ -0,0 +1,26 @@
+package scala.concurrent;
+
+class SyncChannel[a]() extends Monitor() {
+ private var data: a = _;
+ private var reading = False;
+ private var writing = False;
+
+ def write(x: a) = synchronized {
+ await(!writing);
+ data = x;
+ writing = True;
+ if (reading) notifyAll();
+ else await(reading)
+ }
+
+ def read: a = synchronized {
+ await(!reading);
+ reading = True;
+ await(writing);
+ val x = data;
+ writing = False;
+ reading = False;
+ notifyAll();
+ x
+ }
+}
diff --git a/sources/scala/concurrent/SyncVar.scala b/sources/scala/concurrent/SyncVar.scala
new file mode 100644
index 0000000000..7f389318a1
--- /dev/null
+++ b/sources/scala/concurrent/SyncVar.scala
@@ -0,0 +1,19 @@
+package scala.concurrent;
+
+class SyncVar[a]() extends Monitor() {
+ private var isDefined: Boolean = False;
+ private var value: a = _;
+ def get = synchronized {
+ if (!isDefined) wait();
+ value
+ }
+ def set(x: a) = synchronized {
+ value = x ; isDefined = True ; notifyAll();
+ }
+ def isSet: Boolean =
+ isDefined;
+ def unset = synchronized {
+ isDefined = False;
+ }
+}
+
diff --git a/sources/scala/concurrent/TIMEOUT.scala b/sources/scala/concurrent/TIMEOUT.scala
new file mode 100644
index 0000000000..5c26cf8611
--- /dev/null
+++ b/sources/scala/concurrent/TIMEOUT.scala
@@ -0,0 +1,3 @@
+package scala.concurrent;
+
+case class TIMEOUT();
diff --git a/sources/scala/concurrent/ops.scala b/sources/scala/concurrent/ops.scala
new file mode 100644
index 0000000000..438a7d58e2
--- /dev/null
+++ b/sources/scala/concurrent/ops.scala
@@ -0,0 +1,39 @@
+package scala.concurrent;
+
+module ops {
+
+ def spawn(def p: Unit) = {
+ val t = new Thread() { override def run() = p; }
+ t.run()
+ }
+
+ def future[a](def p: a): () => a = {
+ val result = new SyncVar[a]();
+ spawn { result set p }
+ () => result.get
+ }
+
+ def par[a, b](def xp: a, def yp: b): Pair[a, b] = {
+ val y = new SyncVar[b]();
+ spawn { y set yp }
+ Pair(xp, y.get)
+ }
+
+ def replicate(start: Int, end: Int)(def p: Int => Unit): Unit = {
+ if (start == end) {
+ } else if (start + 1 == end) {
+ p(start)
+ } else {
+ val mid = (start + end) / 2;
+ spawn { replicate(start, mid)(p) }
+ replicate(mid, end)(p)
+ }
+ }
+
+ def parMap[a,b](f: a => b, xs: Array[a]): Array[b] {
+ val results = new Array[b](xs.length);
+ replicate(0, xs.length) { i => results(i) = f(xs(i)) }
+ results
+ }
+}
+
diff --git a/sources/scalac/transformer/UnCurry.java b/sources/scalac/transformer/UnCurry.java
index 172351216b..dac20cba6d 100644
--- a/sources/scalac/transformer/UnCurry.java
+++ b/sources/scalac/transformer/UnCurry.java
@@ -68,6 +68,7 @@ public class UnCurry extends OwnerTransformer
* (a_1, ..., a_n) => (Tuple(a_1, ..., a_n))
*/
public Tree transform(Tree tree) {
+ //new scalac.ast.printer.TextTreePrinter().print("uncurry: ").print(tree).println().end();//DEBUG
//uncurry type and symbol
if (tree.type != null) tree.type = descr.uncurry(tree.type);
switch (tree) {
@@ -80,7 +81,6 @@ public class UnCurry extends OwnerTransformer
case DefDef(int mods, Name name, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs):
Tree rhs1 = transform(rhs, tree.symbol());
- if (global.debug) global.log(name + ":" + rhs1.type);//debug
return copy.DefDef(
tree, mods, name, tparams,
uncurry(transform(vparams, tree.symbol())),
@@ -141,12 +141,19 @@ public class UnCurry extends OwnerTransformer
}
}
+// java.util.HashSet visited = new java.util.HashSet();//DEBUG
+
/** Transform arguments `args' to method with type `methtype'.
*/
private Tree[] transformArgs(int pos, Tree[] args, Type methtype) {
+// if (args.length != 0 && visited.contains(args)) {
+// new scalac.ast.printer.TextTreePrinter().print("dup args: ").print(make.Block(pos, args)).println().end();//DEBUG
+// assert false;
+// }
+// visited.add(args);//DEBUG
+
switch (methtype) {
case MethodType(Symbol[] params, _):
- Tree[] args0 = args;//debug
if (params.length == 1 && (params[0].flags & REPEATED) != 0) {
assert (args.length != 1 || !(args[0] instanceof Tree.Tuple));
args = new Tree[]{make.Tuple(pos, args).setType(params[0].type())};
@@ -174,21 +181,23 @@ public class UnCurry extends OwnerTransformer
* convert argument `e' to (expansion of) `() => e'
*/
private Tree transformArg(Tree arg, Symbol formal) {
- Tree arg1 = transform(arg);
if ((formal.flags & DEF) != 0) {
Symbol sym = arg.symbol();
if (sym != null && (sym.flags & DEF) != 0) {
+ Tree arg1 = transform(arg);
switch (arg1) {
case Apply(Select(Tree qual, Name name), Tree[] args1):
assert name == Names.apply && args1.length == 0;
return qual;
default:
- global.debugPrinter.print(arg);//debug
+ global.debugPrinter.print(arg1).flush();//debug
throw new ApplicationError();
}
}
- return transform(gen.mkUnitFunction(
- arg, descr.uncurry(arg1.type), currentOwner));
- } else return arg1;
+ return transform(
+ gen.mkUnitFunction(arg, descr.uncurry(arg.type), currentOwner));
+ } else {
+ return transform(arg);
+ }
}
}
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index db3e09f50c..f6400b3872 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -162,14 +162,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
else throw new ApplicationError();
}
- Tree error(Tree tree, String msg) {
- unit.error(tree.pos, msg);
- if (tree.hasSymbol()) tree = tree.setSymbol(Symbol.ERROR);
- return tree.setType(Type.ErrorType);
+ Tree errorTree(int pos) {
+ return make.Bad(pos).setSymbol(Symbol.ERROR).setType(Type.ErrorType);
}
- void error(int pos, String msg) {
+ Tree error(int pos, String msg) {
unit.error(pos, msg);
+ return errorTree(pos);
}
void typeError(int pos, Type found, Type req) {
@@ -529,7 +528,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (TreeInfo.isPureExpr(tree) || tree.type == Type.ErrorType) return tree;
//new TextTreePrinter().print(tree).end();//DEBUG
//System.out.println(" " + tree.type);//DEBUG
- return error(tree, "stable identifier required");
+ return error(tree.pos, "stable identifier required");
}
/** Check that (abstract) type can be instantiated.
@@ -749,6 +748,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
other.moduleClass());
sym.moduleClass().constructor().copyTo(
other.moduleClass().constructor());
+ other.moduleClass().constructor().setInfo(
+ Type.MethodType(
+ Symbol.EMPTY_ARRAY,
+ other.moduleClass().typeConstructor()));
}
return other;
} else if (sym.kind == VAL && other.kind == VAL) {
@@ -1050,7 +1053,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
// evaluate what was found
if (sym1.kind == NONE) {
if (sym.kind == NONE) {
- return error(tree, "not found: " + decode(name));
+ return error(tree.pos, "not found: " + decode(name));
} else {
sym.flags |= ACCESSED;
if (sym.owner().kind == CLASS)
@@ -1059,7 +1062,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
pre = Type.localThisType;
}
} else if (sym.kind != NONE && !sym.isPreloaded()) {
- return error(tree,
+ return error(tree.pos,
"reference to " + name + " is ambiguous;\n" +
"it is both defined in " + sym.owner() +
" and imported subsequently by \n" + nextimports.tree);
@@ -1069,7 +1072,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
nextimports.enclscope == lastimports.enclscope) {
if (!nextimports.sameImport(lastimports) &&
nextimports.importedSymbol(name).kind != NONE) {
- return error(tree,
+ return error(tree.pos,
"reference to " + name + " is ambiguous;\n" +
"it is imported twice in the same scope by\n " +
lastimports.tree + "\nand " + nextimports.tree);
@@ -1105,10 +1108,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Symbol sym = qual.type.lookup(name);
if (sym.kind == NONE) {
//System.out.println(qual.type + " has members " + qual.type.members());//DEBUG
- return error(tree,
- decode(name) + " is not a member of " + qual.type);
+ return error(tree.pos,
+ decode(name) + " is not a member of " + qual.type.widen());
} else if (!isAccessible(sym, qual)) {
- return error(tree, sym + " cannot be accessed in " + qual.type);
+ return error(tree.pos, sym + " cannot be accessed in " + qual.type);
} else {
sym.flags |= (ACCESSED | SELECTOR);
Type symtype = qual.type.memberType(sym);
@@ -1212,8 +1215,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
pushContext(constrs[i], context.owner, context.scope);
context.delayArgs = delayArgs;
constrs[i] = transform(constrs[i], CONSTRmode, pt);
- Symbol c = TreeInfo.methSymbol(constrs[i]).primaryConstructorClass();
- if (c.kind == CLASS) c.initialize();//to detect cycles
+ Symbol f = TreeInfo.methSymbol(constrs[i]);
+ if (f != null) {
+ Symbol c = f.primaryConstructorClass();
+ if (c.kind == CLASS) c.initialize();//to detect cycles
+ }
popContext();
}
return constrs;
@@ -1301,7 +1307,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (context.delayArgs) {
switch (fn1.type) {
case MethodType(_, Type restp):
- return tree.setType(restp);
+ return copy.Apply(tree, fn1, args).setType(restp);
}
}
@@ -1326,7 +1332,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
try {
infer.methodAlternative(fn1, alts, alttypes, argtypes, pt);
} catch (Type.Error ex) {
- error(tree, ex.msg);
+ error(tree.pos, ex.msg);
}
}
@@ -1337,7 +1343,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
try {
fn1 = infer.methodInstance(fn1, tparams, restp, argtypes);
} catch (Type.Error ex) {
- error(tree, ex.msg);
+ error(tree.pos, ex.msg);
}
switch (fn1.type) {
case MethodType(Symbol[] params, Type restp1):
@@ -1362,7 +1368,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
return tree.setType(Type.ErrorType);
//new TextTreePrinter().print(tree).println().end();//DEBUG
- return error(tree,
+ return error(tree.pos,
infer.applyErrorMsg(
"", fn1, " cannot be applied to ", argtypes, pt));
@@ -1474,7 +1480,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
try {
infer.exprAlternative(tree, alts, alttypes, pt);
} catch (Type.Error ex) {
- error(tree, ex.msg);
+ error(tree.pos, ex.msg);
}
switch (tree.type) {
case OverloadedType(_, _):
@@ -1497,7 +1503,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
try {
tree = infer.exprInstance(tree, tparams, restp, pt);
} catch (Type.Error ex) {
- error(tree, ex.msg);
+ tree = error(tree.pos, ex.msg);
}
return adapt(tree, mode, pt);
} else if ((mode & EXPRmode) != 0) {
@@ -1513,7 +1519,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
checkEtaExpandable(tree.pos, tree.type);
return transform(desugarize.etaExpand(tree, tree.type), mode, pt);
} else if ((mode & (CONSTRmode | FUNmode)) == CONSTRmode) {
- return error(tree, "missing arguments for class constructor");
+ return error(tree.pos, "missing arguments for class constructor");
}
}
if ((mode & FUNmode) != 0) {
@@ -1537,11 +1543,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (seqtp != Type.NoType) {
tree.type = seqConstructorType(seqtp, pt);
} else {
- error(tree, "expected pattern type " + pt +
+ error(tree.pos, "expected pattern type " + pt +
" does not conform to sequence " + clazz);
}
} else {
- error(tree, tree.symbol() +
+ error(tree.pos, tree.symbol() +
" is neither a case class constructor nor a sequence class constructor");
}
return tree;
@@ -1610,7 +1616,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Symbol sym = tree1.symbol();
if ((mode & FUNmode) == 0 && sym != null && sym.typeParams().length != 0)
- return error(tree, sym + " takes type parameters.");
+ return error(tree.pos, sym + " takes type parameters.");
else
return tree1;
}
@@ -1632,8 +1638,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
switch (tree) {
case Bad():
- tree.setType(Type.ErrorType);
- return tree;
+ return tree.setSymbol(Symbol.ERROR).setType(Type.ErrorType);
case Empty:
tree.type = Type.NoType;
@@ -1764,7 +1769,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
desugarize.partialFunction(
tree, pattpe, restpe.dropVariance()));
} else {
- return error(tree, "expected pattern type of cases could not be determined");
+ return error(tree.pos, "expected pattern type of cases could not be determined");
}
} else {
return transform(desugarize.Visitor(tree));
@@ -1779,7 +1784,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (varsym != null && (varsym.flags & ACCESSOR) != 0) {
return transform(desugarize.Assign(tree.pos, lhs, rhs));
} else if (varsym == null || (varsym.flags & MUTABLE) == 0) {
- return error(tree, "assignment to non-variable");
+ return error(tree.pos, "assignment to non-variable");
} else {
Tree rhs1 = transform(rhs, EXPRmode, lhs1.type);
return copy.Assign(tree, lhs1, rhs1)
@@ -1828,8 +1833,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
enterSym(cd);
cd = transform(cd);
Symbol clazz = cd.symbol();
- if (clazz.kind != CLASS)
- return Tree.Bad().setType(Type.ErrorType);
+ if (clazz.kind != CLASS) return errorTree(tree.pos);
// compute template's type with new refinement scope.
Type[] parentTypes = clazz.info().parents();
@@ -1896,7 +1900,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
try {
infer.polyAlternative(fn1, alts, alttypes, args.length);
} catch (Type.Error ex) {
- error(tree, ex.msg);
+ error(tree.pos, ex.msg);
}
}
@@ -1919,7 +1923,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
case ErrorType:
return tree.setType(Type.ErrorType);
}
- return error(tree,
+ return error(tree.pos,
infer.toString(fn1.symbol(), fn1.type) +
" cannot be applied to " +
ArrayApply.toString(argtypes, "[", ",", "]"));
@@ -1959,7 +1963,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
throw new ApplicationError();
}
} else {
- return error(tree,
+ return error(tree.pos,
"super can be used only in a class, module, or template");
}
@@ -1975,7 +1979,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
.setSymbol(clazz).setType(clazz.type()));
} else {
return error(
- tree, tree +
+ tree.pos, tree +
" can be used only in a class, module, or template");
}
} else {
@@ -1986,11 +1990,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (clazzContext != Context.NONE) {
tree1 = tree;
} else {
- return error(
- qual, clazz.name + " is not an enclosing class");
+ return error(qual.pos,
+ clazz.name + " is not an enclosing class");
}
} else {
- return error(qual, "class identifier expected");
+ return error(qual.pos, "class identifier expected");
}
}
return tree1.setType(
diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java
index 2a5a638004..7423d0664d 100644
--- a/sources/scalac/typechecker/Infer.java
+++ b/sources/scalac/typechecker/Infer.java
@@ -71,8 +71,6 @@ public class Infer implements Modifiers, Kinds {
/** Is type `tp' a parameterized method type?
*/
- /** Is type `tp' a parameterized method type?
- */
boolean isParameterized(Type tp) {
switch (tp) {
case MethodType(_, _): return true;
@@ -766,6 +764,15 @@ public class Infer implements Modifiers, Kinds {
public void exprAlternative(Tree tree, Symbol[] alts,
Type[] alttypes, Type pt)
throws Type.Error {
+ if (alts.length > 0) {
+ int i = 0;
+ while (i < alts.length &&
+ alts[i].isConstructor() &&
+ alttypes[i] instanceof Type.MethodType)
+ i++;
+ if (i == alts.length)
+ throw new Type.Error("missing arguments for " + alts[0]);
+ }
if (alts.length == 1) {
tree.setSymbol(alts[0]).setType(alttypes[0]);
return;