From d5da7d9aa5a8d4833775454853e81ead20cc37a7 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 10 Mar 2003 11:55:36 +0000 Subject: *** empty log message *** --- config/list/library.lst | 6 +- sources/examples/ComputeServer.scala | 32 +++++++++++ sources/examples/boundedbuffer.scala | 30 ++++++++++ sources/examples/futures.scala | 12 ++++ sources/scala/LinkedList.scala | 13 +++++ sources/scala/Monitor.scala | 14 ++--- sources/scala/NativeMonitor.java | 14 +++++ sources/scala/Predef.scala | 89 +++++++++++++++--------------- sources/scala/concurrent/Channel.scala | 21 +++++++ sources/scala/concurrent/Lock.scala | 14 +++++ sources/scala/concurrent/SyncChannel.scala | 26 +++++++++ sources/scala/concurrent/SyncVar.scala | 19 +++++++ sources/scala/concurrent/TIMEOUT.scala | 3 + sources/scala/concurrent/ops.scala | 39 +++++++++++++ sources/scalac/transformer/UnCurry.java | 23 +++++--- sources/scalac/typechecker/Analyzer.java | 78 +++++++++++++------------- sources/scalac/typechecker/Infer.java | 11 +++- 17 files changed, 341 insertions(+), 103 deletions(-) create mode 100644 sources/examples/ComputeServer.scala create mode 100644 sources/examples/boundedbuffer.scala create mode 100644 sources/examples/futures.scala create mode 100644 sources/scala/LinkedList.scala create mode 100644 sources/scala/NativeMonitor.java create mode 100644 sources/scala/concurrent/Channel.scala create mode 100644 sources/scala/concurrent/Lock.scala create mode 100644 sources/scala/concurrent/SyncChannel.scala create mode 100644 sources/scala/concurrent/SyncVar.scala create mode 100644 sources/scala/concurrent/TIMEOUT.scala create mode 100644 sources/scala/concurrent/ops.scala 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 @@ -69,8 +69,6 @@ public class Infer implements Modifiers, Kinds { return tp.typeParams().length > 0; } - /** Is type `tp' a parameterized method type? - */ /** Is type `tp' a parameterized method type? */ boolean isParameterized(Type tp) { @@ -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; -- cgit v1.2.3