diff options
25 files changed, 298 insertions, 217 deletions
diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala index 911c1a6af8..aa05688fc9 100644 --- a/sources/scala/Predef.scala +++ b/sources/scala/Predef.scala @@ -14,10 +14,7 @@ package scala { mkList(x.elements); } - def error[a](x: String):a = (new java.lang.RuntimeException(x)).throw; - - def ConsStream[a](hd: a, def tl: Stream[a]): Stream[a] = - new ConsStreamClass(hd, () => tl); + 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); diff --git a/sources/scala/Stream.scala b/sources/scala/Stream.scala index 2211517eed..5c631cfd7b 100644 --- a/sources/scala/Stream.scala +++ b/sources/scala/Stream.scala @@ -12,29 +12,29 @@ trait Stream[a] { def append(def rest: Stream[a]): Stream[a] = if (isEmpty) rest - else ConsStream(head, tail.append(rest)); + else Stream.cons(head, tail.append(rest)); def init: Stream[a] = - if (isEmpty) error("EmptyStream.init") - else if (tail.isEmpty) new EmptyStream[a]() - else ConsStream(head, tail.init); + if (isEmpty) error("Stream.empty.init") + else if (tail.isEmpty) Stream.empty[a] + else Stream.cons(head, tail.init); def last: a = - if (isEmpty) error("EmptyStream.last") + if (isEmpty) error("Stream.empty.last") else if (tail.isEmpty) head else tail.last; def takeWhile(p: a => Boolean): Stream[a] = - if (isEmpty || !p(head)) new EmptyStream[a]() - else ConsStream(head, tail.takeWhile(p)); + if (isEmpty || !p(head)) Stream.empty[a] + else Stream.cons(head, tail.takeWhile(p)); def dropWhile(p: a => Boolean): Stream[a] = if (isEmpty || !p(head)) this else tail.dropWhile(p); def take(n: Int): Stream[a] = - if (n == 0) new EmptyStream[a]() - else ConsStream(head, tail.take(n-1)); + if (n == 0) Stream.empty[a] + else Stream.cons(head, tail.take(n-1)); def drop(n: Int): Stream[a] = if (n == 0) this @@ -43,8 +43,8 @@ trait Stream[a] { def at(n: Int) = drop(n).head; def map[b](f: a => b): Stream[b] = - if (isEmpty) new EmptyStream[b]() - else ConsStream(f(head), tail.map(f)); + if (isEmpty) Stream.empty[b] + else Stream.cons(f(head), tail.map(f)); def foreach(f: a => Unit): Unit = if (isEmpty) {} @@ -52,7 +52,7 @@ trait Stream[a] { def filter(p: a => Boolean): Stream[a] = if (isEmpty) this - else if (p(head)) ConsStream(head, tail.filter(p)) + else if (p(head)) Stream.cons(head, tail.filter(p)) else tail.filter(p); def forall(p: a => Boolean): Boolean = @@ -81,12 +81,12 @@ trait Stream[a] { else op(head, tail.foldRight(op)(z)); def flatMap[b](f: a => Stream[b]): Stream[b] = - if (isEmpty) new EmptyStream[b]() + if (isEmpty) Stream.empty[b] else f(head).append(tail.flatMap(f)); def reverse: Stream[a] = { - def snoc(xs: Stream[a], x: a): Stream[a] = ConsStream(x, xs); - fold(snoc)(new EmptyStream[a]()) + def snoc(xs: Stream[a], x: a): Stream[a] = Stream.cons(x, xs); + fold(snoc)(Stream.empty[a]) } // The following method is not compilable without run-time type @@ -104,14 +104,45 @@ trait Stream[a] { } def zip[b](that: Stream[b]): Stream[Tuple2[a, b]] = - if (this.isEmpty || that.isEmpty) new EmptyStream[Tuple2[a, b]]() - else ConsStream(Tuple2(this.head, that.head), this.tail.zip(that.tail)); + if (this.isEmpty || that.isEmpty) Stream.empty[Tuple2[a, b]] + else Stream.cons(Tuple2(this.head, that.head), this.tail.zip(that.tail)); def print: Unit = - if (isEmpty) System.out.println("EmptyStream") + if (isEmpty) System.out.println("Stream.empty") else { System.out.print(head as java.lang.Object); System.out.print(", "); tail.print } } + +module Stream { + + def empty[c]: Stream[c] = new Stream[c] { + def isEmpty = True; + def head: c = error("head of empty stream"); + def tail: Stream[c] = error("tail of empty stream"); + override def toString(): String = "Stream.empty"; + } + + def cons[b](hd: b, def tl: Stream[b]): Stream[b] = new Stream[b] { + def isEmpty = False; + def head = hd; + private var tlVal: Stream[b] = _; + private var tlDefined: Boolean = False; + def tail: Stream[b] = { + if (!tlDefined) { tlVal = tl; tlDefined = True; } + tlVal + } + override def toString(): String = "ConsStream(" + hd + ", ?)"; + } + + def concat[a](xs: Seq[Stream[a]]): Stream[a] = concat(xs.elements); + + def concat[a](xs: Iterator[Stream[a]]): Stream[a] = { + if (xs.hasNext) xs.next append concat(xs) + else empty; + } +} + +case class Foo() diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java index 2db39f2b89..d9aa03947b 100644 --- a/sources/scalac/Global.java +++ b/sources/scalac/Global.java @@ -15,7 +15,7 @@ import scalac.ast.*; import scalac.ast.parser.*; import scalac.symtab.Definitions; import scalac.ast.printer.*; -import scalac.backend.Primitives; +//import scalac.backend.Primitives; /** The global environment of a compiler run @@ -90,7 +90,7 @@ public class Global { /** the global primitives */ - public Primitives primitives; + //public Primitives primitives; /** compilation phases. */ @@ -165,7 +165,7 @@ public class Global { this.make = new TreeCreator(); this.currentPhase = PhaseDescriptor.INITIAL; this.definitions = new Definitions(this); - this.primitives = new Primitives(this); + //this.primitives = new Primitives(this); this.treeGen = new TreeGen(this, make); this.PHASE = args.phases; List phases = new ArrayList(); @@ -179,8 +179,7 @@ public class Global { phases.add(PHASE.OPTIMIZE); } */ phases.add(PHASE.TRANSMATCH); - - //phases.add(PHASE.LAMBDALIFT); + phases.add(PHASE.LAMBDALIFT); phases.add(PHASE.EXPLICITOUTER); phases.add(PHASE.ADDACCESSORS); phases.add(PHASE.ADDINTERFACES); @@ -192,8 +191,8 @@ public class Global { } if (target == TARGET_JAVA) phases.add(PHASE.GENJAVA); if (target == TARGET_MSIL) phases.add(PHASE.GENMSIL); - */ if (target == TARGET_JVM) phases.add(PHASE.GENJVM); + */ phases.add(PHASE.TERMINAL); this.phases = new PhaseDescriptor[phases.size()]; for (int i = 0; i < phases.size(); i++) { diff --git a/sources/scalac/PhaseRepository.java b/sources/scalac/PhaseRepository.java index 378b6555e4..75dd0068ef 100644 --- a/sources/scalac/PhaseRepository.java +++ b/sources/scalac/PhaseRepository.java @@ -24,8 +24,8 @@ import scalac.optimizer.OptimizePhase; import scalac.backend.AddConstructorsPhase; import scalac.backend.msil.GenMSILPhase; import scalac.jaco.GenJavaPhase; -*/ import scalac.backend.jvm.GenJVMPhase; +*/ public class PhaseRepository { @@ -58,8 +58,8 @@ public class PhaseRepository { ADDCONSTRUCTORS = new AddConstructorsPhase(), GENMSIL = new GenMSILPhase(), GENJAVA = new GenJavaPhase(), - */ GENJVM = new GenJVMPhase(), + */ TERMINAL = PhaseDescriptor.TERMINAL, }; } @@ -85,8 +85,8 @@ public class PhaseRepository { public final AddConstructorsPhase ADDCONSTRUCTORS; public final GenMSILPhase GENMSIL; public final GenJavaPhase GENJAVA; - */ public final GenJVMPhase GENJVM; + */ public final PhaseDescriptor TERMINAL; //######################################################################## diff --git a/sources/scalac/ast/TreeInfo.java b/sources/scalac/ast/TreeInfo.java index 81d9481f31..75d6dfa863 100644 --- a/sources/scalac/ast/TreeInfo.java +++ b/sources/scalac/ast/TreeInfo.java @@ -120,6 +120,15 @@ public class TreeInfo { } } + public static boolean isVarPattern(Tree pat) { + switch (pat) { + case Ident(Name name): + return name.isVariable(); + default: + return false; + } + } + /** The method symbol of an application node, or Symbol.NONE, if none exists. */ public static Symbol methSymbol(Tree tree) { diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java index f9aa54cb3a..7455080054 100644 --- a/sources/scalac/ast/parser/Parser.java +++ b/sources/scalac/ast/parser/Parser.java @@ -15,6 +15,8 @@ import scalac.symtab.Modifiers; import scalac.ast.*; import Tree.*; +//todo: add type idents? + /** A recursive descent parser for the programming language Scala. * * @author Martin Odersky, Matthias Zenger @@ -186,71 +188,32 @@ public class Parser implements Tokens { } } - /** Create tree representing type scala.Any - */ - Tree scalaAnyType(int pos) { - return make.Select(pos, make.Ident(pos, Names.scala), Names.Any.toTypeName()); - } - - /** Create tree representing type scala.Seq - */ - Tree scalaSeqType(int pos) { - return make.Select(pos, make.Ident(pos, Names.scala), Names.Seq.toTypeName()); - } - - /** Create tree representing constructor scala.Object - */ - Tree scalaObjectConstr(int pos) { - return make.Select(pos, make.Ident(pos, Names.scala), Names.Object.toConstrName()); - } - /** Create tree representing method scala.Symbol - */ - Tree scalaSymbol(int pos) { - return make.Select(pos, make.Ident(pos, Names.scala), Names.Symbol); - } - - /** Create tree representing method scala.Labelled - */ - Tree scalaLabelled(int pos) { - return make.Select(pos, make.Ident(pos, Names.scala), Names.Labelled); - } - - /** Create tree representing method scala.Predef.List - */ - Tree scalaPredefList(int pos) { - return make.Select(pos, - make.Select(pos, make.Ident(pos, Names.scala), Names.Predef), - Names.List); - } - - /** Create tree representing type scala.List - */ - Tree scalaListType(int pos) { - return make.Select(pos, make.Ident(pos, Names.scala), Names.List.toTypeName()); + Tree scalaDot(int pos, Name name) { + return make.Select(pos, make.Ident(pos, Names.scala), name); } /** Create tree for for-comprehension <for (enums) do body> or * <for (enums) yield body> where mapName and flatmapName are chosen * corresponding to whether this is a for-do or a for-yield. */ - Tree makeFor(Tree[] enums, Name mapName, Name flatmapName, Tree body) { + Tree makeFor(int pos, Tree[] enums, Name mapName, Name flatmapName, Tree body) { switch (enums[0]) { case PatDef(int mods, Tree pat, Tree rhs): if (enums.length == 1) - return makeFor1(enums[0].pos, mapName, pat, rhs, body); + return makeFor1(pos, mapName, pat, rhs, body); Tree[] newenums = new Tree[enums.length - 1]; switch (enums[1]) { case PatDef(int mods2, Tree pat2, Tree rhs2): System.arraycopy(enums, 1, newenums, 0, newenums.length); - return makeFor1(enums[0].pos, flatmapName, pat, rhs, - makeFor(newenums, mapName, flatmapName, body)); + return makeFor1(pos, flatmapName, pat, rhs, + makeFor(enums[1].pos, newenums, mapName, flatmapName, body)); default: System.arraycopy(enums, 2, newenums, 1, newenums.length - 1); newenums[0] = make.PatDef( enums[0].pos, mods, pat, - makeFor1(enums[0].pos, Names.filter, pat, rhs, enums[1])); - return makeFor(newenums, mapName, flatmapName, body); + makeFor1(enums[1].pos, Names.filter, pat, rhs, enums[1])); + return makeFor(pos, newenums, mapName, flatmapName, body); } default: throw new ApplicationError(); @@ -493,17 +456,17 @@ public class Parser implements Tokens { t = make.Ident(s.pos, Names.null_); break; case SYMBOLLIT: - Tree symt = scalaSymbol(s.pos); + Tree symt = scalaDot(s.pos, Names.Symbol); if (isPattern) symt = convertToTypeId(symt); t = make.Apply(s.pos, symt, new Tree[]{make.Literal(s.pos, s.name.toString())}); s.nextToken(); if (s.token == LPAREN || s.token == LBRACE) { - Tree labt = scalaLabelled(s.pos); + Tree labt = scalaDot(s.pos, Names.Labelled); if (isPattern) labt = convertToTypeId(labt); - Tree listt = isPattern ? scalaListType(s.pos) - : scalaPredefList(s.pos); + Tree listt = isPattern ? scalaDot(s.pos, Names.List.toTypeName()) + : make.Select(s.pos, scalaDot(s.pos, Names.Predef), Names.List); t = make.Apply(s.pos, labt, new Tree[]{t, make.Apply(s.pos, listt, argumentExprs())}); @@ -707,11 +670,9 @@ public class Parser implements Tokens { Tree[] enums = enumerators(); accept(RPAREN); if (s.token == DO) { - s.nextToken(); - return makeFor(enums, Names.foreach, Names.foreach, expr()); + return makeFor(s.skipToken(), enums, Names.foreach, Names.foreach, expr()); } else if (s.token == YIELD) { - s.nextToken(); - return makeFor(enums, Names.map, Names.flatmap, expr()); + return makeFor(s.skipToken(), enums, Names.map, Names.flatmap, expr()); } else { return syntaxError("`do' or `yield' expected", true); } @@ -962,9 +923,26 @@ public class Parser implements Tokens { */ Tree generator() { int pos = accept(VAL); - Tree p = pattern(); + Tree pat = pattern(); accept(LARROW); - return make.PatDef(pos, 0, p, expr()); + Tree rhs = expr(); + if (!TreeInfo.isVarPattern(pat)) + rhs = make.Apply( + rhs.pos, + make.Select(rhs.pos, rhs, Names.filter), + new Tree[]{ + make.Visitor( + rhs.pos, + new Tree.CaseDef[]{ + (CaseDef)make.CaseDef( + rhs.pos, pat, Tree.Empty, + make.Select(rhs.pos, + scalaDot(rhs.pos, Names.Boolean), Names.True)), + (CaseDef)make.CaseDef( + rhs.pos, make.Ident(rhs.pos, Names.WILDCARD), Tree.Empty, + make.Select(rhs.pos, + scalaDot(rhs.pos, Names.Boolean), Names.False))})}); + return make.PatDef(pos, 0, pat, rhs); } //////// PATTERNS //////////////////////////////////////////////////////////// @@ -989,11 +967,8 @@ public class Parser implements Tokens { int base = sp; Tree top = simplePattern(); if (s.token == COLON) { - switch (top) { - case Ident(Name name): - if (name.isVariable()) - return make.Typed(s.skipToken(), top, type1()); - } + if (TreeInfo.isVarPattern(top)) + return make.Typed(s.skipToken(), top, type1()); } while (s.token == IDENTIFIER) { top = reduceStack( @@ -1159,7 +1134,9 @@ public class Parser implements Tokens { if (s.token == IDENTIFIER && s.name == STAR) { s.nextToken(); mods |= Modifiers.REPEATED; - tp = make.AppliedType(tp.pos, scalaSeqType(tp.pos), new Tree[]{tp}); + tp = make.AppliedType(tp.pos, + scalaDot(tp.pos, Names.Seq.toTypeName()), + new Tree[]{tp}); } return (ValDef)make.ValDef(pos, mods, name, tp, Tree.Empty); } @@ -1190,7 +1167,7 @@ public class Parser implements Tokens { s.nextToken(); tp = type(); } else { - tp = scalaAnyType(pos); + tp = scalaDot(pos, Names.Any.toTypeName()); } return make.TypeDef(pos, Modifiers.PARAM, name.toTypeName(), Tree.ExtTypeDef.EMPTY_ARRAY, tp); @@ -1390,7 +1367,7 @@ public class Parser implements Tokens { if (tp == Tree.Empty || s.token == EQUALS) return make.ValDef(pos, mods, name, tp, equalsExpr()); else - return make.ValDef(pos, mods | Modifiers.ABSTRACT, name, tp, Tree.Empty); + return make.ValDef(pos, mods | Modifiers.DEFERRED, name, tp, Tree.Empty); default: return make.PatDef(pos, mods, pat, equalsExpr()); } @@ -1415,7 +1392,7 @@ public class Parser implements Tokens { } return make.ValDef(pos, mods | Modifiers.MUTABLE, name, type, rhs); } else { - return make.ValDef(pos, mods | Modifiers.MUTABLE | Modifiers.ABSTRACT, + return make.ValDef(pos, mods | Modifiers.MUTABLE | Modifiers.DEFERRED, name, type, Tree.Empty); } } @@ -1437,7 +1414,7 @@ public class Parser implements Tokens { return make.DefDef(pos, mods, name, tparams, vparams, restype, equalsExpr()); else - return make.DefDef(pos, mods | Modifiers.ABSTRACT, name, + return make.DefDef(pos, mods | Modifiers.DEFERRED, name, tparams, vparams, restype, Tree.Empty); } @@ -1458,7 +1435,7 @@ public class Parser implements Tokens { return make.DefDef(pos, mods, name, tparams, vparams, restype, (s.token == LBRACE) ? blockConstr() : constr()); } else - return make.DefDef(pos, mods | Modifiers.ABSTRACT, name, + return make.DefDef(pos, mods | Modifiers.DEFERRED, name, tparams, vparams, restype, Tree.Empty); } @@ -1470,7 +1447,7 @@ public class Parser implements Tokens { Name name = ident().toTypeName(); if (s.token == SUBTYPE) { s.nextToken(); - return make.TypeDef(pos, mods | Modifiers.ABSTRACT, name, + return make.TypeDef(pos, mods | Modifiers.DEFERRED, name, Tree.ExtTypeDef.EMPTY_ARRAY, type()); } else if (s.token == LBRACKET) { TypeDef[] tparams = typeParamClauseOpt(); @@ -1482,8 +1459,8 @@ public class Parser implements Tokens { Tree.ExtTypeDef.EMPTY_ARRAY, type()); } else if (s.token == SEMI || s.token == COMMA) { return make.TypeDef( - pos, mods | Modifiers.ABSTRACT, name, - Tree.ExtTypeDef.EMPTY_ARRAY, scalaAnyType(pos)); + pos, mods | Modifiers.DEFERRED, name, + Tree.ExtTypeDef.EMPTY_ARRAY, scalaDot(pos, Names.Any.toTypeName())); } else { return syntaxError("`=' or `<:' expected", true); } @@ -1519,12 +1496,14 @@ public class Parser implements Tokens { s.nextToken(); return template(); } else if (s.token == LBRACE) { - return (Template)make.Template( - pos, new Tree[]{scalaObjectConstr(pos)}, templateBody()); + return (Template)make.Template(pos, + new Tree[]{scalaDot(pos, Names.Object.toConstrName())}, + templateBody()); } else { syntaxError("`extends' or `{' expected", true); - return (Template)make.Template( - pos, new Tree[]{scalaObjectConstr(pos)}, Tree.EMPTY_ARRAY); + return (Template)make.Template(pos, + new Tree[]{scalaDot(pos, Names.Object.toConstrName())}, + Tree.EMPTY_ARRAY); } } diff --git a/sources/scalac/ast/printer/TextTreePrinter.java b/sources/scalac/ast/printer/TextTreePrinter.java index 58010b8412..5836e24f0e 100644 --- a/sources/scalac/ast/printer/TextTreePrinter.java +++ b/sources/scalac/ast/printer/TextTreePrinter.java @@ -275,7 +275,11 @@ public class TextTreePrinter implements TreePrinter { print(Text.Space); printSymbolDefinition(tree.symbol(), name); printOpt(TXT_COLON, tpe, false); - printOpt(TXT_EQUAL, rhs, true); + if ((mods & Modifiers.DEFERRED) == 0) { + print(Text.Space); print(TXT_EQUAL); print(Text.Space); + if (rhs == Tree.Empty) print("_"); + else print(rhs); + } break; case PatDef(int mods, Tree pat, Tree rhs): @@ -311,7 +315,7 @@ public class TextTreePrinter implements TreePrinter { print(Text.Space); printSymbolDefinition(tree.symbol(), name); printParams(tparams); - if ((mods & (Modifiers.ABSTRACT | Modifiers.PARAM)) != 0) printOpt(TXT_SUBTYPE, rhs, true); + if ((mods & (Modifiers.DEFERRED | Modifiers.PARAM)) != 0) printOpt(TXT_SUBTYPE, rhs, true); else printOpt(TXT_EQUAL, rhs, true); break; @@ -514,6 +518,7 @@ public class TextTreePrinter implements TreePrinter { print(TXT_UNKNOWN); break; } + //print("{" + tree.type + "}");//DEBUG return this; } @@ -575,7 +580,7 @@ public class TextTreePrinter implements TreePrinter { } protected void printModifiers(int flags) { - if ((flags & Modifiers.ABSTRACT) != 0) { + if ((flags & Modifiers.ABSTRACTCLASS) != 0) { print(KW_ABSTRACT); print(Text.Space); } diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java index 38f5a042d6..b9b5dc7463 100644 --- a/sources/scalac/symtab/Modifiers.java +++ b/sources/scalac/symtab/Modifiers.java @@ -11,7 +11,7 @@ package scalac.symtab; public interface Modifiers { // modifiers - int ABSTRACT = 0x00000001; + int DEFERRED = 0x00000001; // was `abstract' for members int FINAL = 0x00000002; int PRIVATE = 0x00000004; int PROTECTED = 0x00000008; @@ -60,7 +60,7 @@ public interface Modifiers { public static class Helper { public static boolean isAbstract(int flags) { - return (flags & (ABSTRACT | ABSTRACTCLASS)) != 0; + return (flags & (DEFERRED | ABSTRACTCLASS)) != 0; } public static boolean isFinal(int flags) { diff --git a/sources/scalac/symtab/NameMangler.java b/sources/scalac/symtab/NameMangler.java index 30de8193d0..7add579fa5 100644 --- a/sources/scalac/symtab/NameMangler.java +++ b/sources/scalac/symtab/NameMangler.java @@ -13,21 +13,11 @@ import java.util.HashMap; public class NameMangler { - private HashMap/*<Symbol,HashMap<Symbol,int[]>>*/ mangleMap = new HashMap(); + private int cnt = 0; public void setMangledName(Symbol innerclazz) { Symbol topclazz = innerclazz.enclToplevelClass(); - HashMap map = (HashMap) mangleMap.get(topclazz); - if (map == null) { - map = new HashMap(); - mangleMap.put(topclazz, map); - } - int[] ctr = (int[]) map.get(innerclazz); - if (ctr == null) { - ctr = new int[1]; - map.put(innerclazz, ctr); - } innerclazz.setMangledName( - Name.fromString(topclazz.name + "$" + (ctr[0]++) + innerclazz.name)); + Name.fromString(topclazz.name + "$" + (cnt++) + innerclazz.name)); } } diff --git a/sources/scalac/symtab/SymSet.java b/sources/scalac/symtab/SymSet.java index f72b9764f5..6911b75c06 100644 --- a/sources/scalac/symtab/SymSet.java +++ b/sources/scalac/symtab/SymSet.java @@ -35,6 +35,30 @@ public class SymSet { } } + public SymSet excl(Symbol sym) { + if (sym == this.sym) { + if (l == EMPTY) return r; + if (r == EMPTY) return l; + SymSet m = r; + if (m.l != EMPTY) { + SymSet p; + do { + p = m; + m = m.l; + } while (m.l != EMPTY); + p.l = m.r; + m.r = r; + } + m.l = l; + return m; + } else if (sym.isLess(this.sym)) { + return new SymSet(this.sym, l.excl(sym), r); + } else { + assert this.sym.isLess(sym); + return new SymSet(this.sym, l, r.excl(sym)); + } + } + /** Is `sym' an element of this set? */ public boolean contains(Symbol sym) { diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index 962c332266..5bfec83e7f 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -564,6 +564,13 @@ public abstract class Symbol implements Modifiers, Kinds { if (diff > 0) return true; if (diff < 0) return false; + diff = that.hashCode() - this.hashCode(); + if (diff > 0) return true; + if (diff < 0) return false; + + if (owner().isLess(that.owner())) return true; + if (that.owner().isLess(owner())) return false; + throw new ApplicationError( "Giving up: can't order two incarnations of class " + this.mangledFullName()); @@ -638,10 +645,10 @@ public abstract class Symbol implements Modifiers, Kinds { */ public String toString() { if (isRoot()) return "<root package>"; - if (isAnonymousClass()) return "<template>"; String kstr = kindString(); String str; - if (kstr.length() == 0) str = fullNameString(); + if (isAnonymousClass()) str = "<template>"; + else if (kstr.length() == 0) str = fullNameString(); else str = kstr + " " + fullNameString(); return str + idString(); } @@ -878,7 +885,8 @@ public class TermSymbol extends Symbol { } /** Get the fully qualified name of this Symbol */ public Name fullName() { - if ((flags & MODUL) != 0) return moduleClass().fullName(); + if (isModule()) return moduleClass().fullName(); + else if (isPrimaryConstructor()) return primaryConstructorClass().fullName(); else return super.fullName(); } diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 54f690f7bb..0fcca1acd2 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -512,12 +512,12 @@ public class Type implements Modifiers, Kinds, TypeTags { // take precedence over abstract ones. int i = parts.length; sym = Symbol.NONE; - while (i > start && (sym.kind == NONE || (sym.flags & ABSTRACT) != 0)) { + while (i > start && (sym.kind == NONE || (sym.flags & DEFERRED) != 0)) { i--; Symbol sym1 = parts[i].lookupNonPrivate(name, i == 0 ? 0 : 1); if (sym1.kind != NONE && (sym1.flags & PRIVATE) == 0 && - (sym.kind == NONE || (sym1.flags & ABSTRACT) == 0)) + (sym.kind == NONE || (sym1.flags & DEFERRED) == 0)) sym = sym1; } return sym; diff --git a/sources/scalac/symtab/classfile/ClassfileParser.java b/sources/scalac/symtab/classfile/ClassfileParser.java index 956c83968f..686b832459 100644 --- a/sources/scalac/symtab/classfile/ClassfileParser.java +++ b/sources/scalac/symtab/classfile/ClassfileParser.java @@ -86,8 +86,8 @@ public class ClassfileParser implements ClassfileConstants { "' contains wrong class " + name); // todo: correct flag transition c.flags = transFlags(flags); - if ((c.flags & Modifiers.ABSTRACT) != 0) - c.flags = c.flags & ~Modifiers.ABSTRACT | Modifiers.ABSTRACTCLASS; + if ((c.flags & Modifiers.DEFERRED) != 0) + c.flags = c.flags & ~Modifiers.DEFERRED | Modifiers.ABSTRACTCLASS; Type supertpe = readClassType(in.nextChar()); Type[] basetpes = new Type[in.nextChar() + 1]; this.locals = new Scope(); @@ -143,7 +143,7 @@ public class ClassfileParser implements ClassfileConstants { else if ((flags & 0x0004) != 0) res |= Modifiers.PROTECTED; if ((flags & 0x0400) != 0) - res |= Modifiers.ABSTRACT; + res |= Modifiers.DEFERRED; if ((flags & 0x0010) != 0) res |= Modifiers.FINAL; if ((flags & 0x0200) != 0) diff --git a/sources/scalac/transformer/AddInterfaces.java b/sources/scalac/transformer/AddInterfaces.java index e8225bd614..46cdfbd2a6 100644 --- a/sources/scalac/transformer/AddInterfaces.java +++ b/sources/scalac/transformer/AddInterfaces.java @@ -716,7 +716,7 @@ class AddInterfaces extends SubstTransformer { ifaceToClass.put(iSym, cSym); ifaceToClass.put(iSym.constructor(), cSym.constructor()); } else { - iSym.flags |= Modifiers.ABSTRACT; + iSym.flags |= Modifiers.DEFERRED; ifaceMemberToClass.put(iSym, cSym); } } diff --git a/sources/scalac/transformer/ExpandMixins.java b/sources/scalac/transformer/ExpandMixins.java index 2b84d9f1fa..7b2804b8b9 100644 --- a/sources/scalac/transformer/ExpandMixins.java +++ b/sources/scalac/transformer/ExpandMixins.java @@ -244,7 +244,7 @@ public class ExpandMixins extends Transformer { Symbol memSymM = bcType.lookupNonPrivate(memName); if (memSymT != memSymM) { - if ((memSym.flags & Modifiers.ABSTRACT) != 0) + if ((memSym.flags & Modifiers.DEFERRED) != 0) leftOutMembers.add(member); else renameSymbol(symbolMap, memSym); diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java index ca37e43996..3eeb6d15b5 100644 --- a/sources/scalac/transformer/LambdaLift.java +++ b/sources/scalac/transformer/LambdaLift.java @@ -104,6 +104,11 @@ public class LambdaLift extends OwnerTransformer */ private SymSet renamable; + /** The set of symbols that bound by polytypes + * and therefore are not free type variables. + */ + private SymSet excluded; + /** A flag to indicate whether new free variables have been found */ private boolean changedFreeVars; @@ -142,7 +147,7 @@ public class LambdaLift extends OwnerTransformer * the owner of sym. */ private boolean markFree(Symbol sym, Symbol owner) { - //if (global.debug) global.log("mark " + sym + " free in " + owner);//DEBUG + if (global.debug) global.log("mark " + sym + " free in " + owner);//debug if (owner.kind == NONE) { assert propagatePhase : sym + " in " + sym.owner(); return false; @@ -175,15 +180,23 @@ public class LambdaLift extends OwnerTransformer public Type apply(Type tp) { switch (tp) { case TypeRef(ThisType(_), Symbol sym, Type[] targs): - if (sym.isLocal() && sym.kind == TYPE) + if (sym.isLocal() && sym.kind == TYPE && !excluded.contains(sym)) markFree(sym, currentOwner); + break; + case PolyType(Symbol[] tparams, Type restp): + for (int i = 0; i < tparams.length; i++) + excluded = excluded.incl(tparams[i]); + Type tp1 = super.map(tp); + for (int i = 0; i < tparams.length; i++) + excluded = excluded.excl(tparams[i]); + return tp1; } return map(tp); } }; public Tree transform(Tree tree) { - //global.debugPrinter.print("free ").print(tree).println().end();//DEBUG + //if (global.debug) global.debugPrinter.print("free ").print(tree).println().end();//DEBUG traverseTypeMap.apply(tree.type.widen()); Symbol sym = tree.symbol(); switch(tree) { @@ -194,8 +207,16 @@ public class LambdaLift extends OwnerTransformer } return super.transform(tree); + case TypeDef(int mods, Name name, TypeDef[] tparams, Tree rhs): + // ignore type definition as owner. + // reason: it might be in a refinement + // todo: handle type parameters? + return copy.TypeDef( + tree, mods, name, + transform(tparams, currentOwner), + transform(rhs, currentOwner)); + case Ident(Name name): - assert sym.owner() != null : sym + " " + name;//debug if (sym.isLocal()) { if (sym.isMethod()) { Symbol f = enclFun(currentOwner); @@ -254,6 +275,7 @@ public class LambdaLift extends OwnerTransformer ftvs = new HashMap(); called = new HashMap(); renamable = SymSet.EMPTY; + excluded = SymSet.EMPTY; apply(unit); propagatePhase = true; @@ -300,14 +322,14 @@ public class LambdaLift extends OwnerTransformer tree, mods, sym.name, addTypeParams(transform(tparams, sym), newtparams), new ValDef[][]{addParams(transform(vparams, sym)[0], newparams)}, - transform(tpe), + transform(tpe, sym), transform(impl, sym)); liftedDefs.append(tree1); return Tree.Empty; } else { return copy.ClassDef( tree, mods, sym.name, - transform(tparams, sym), transform(vparams, sym), transform(tpe), + transform(tparams, sym), transform(vparams, sym), transform(tpe, sym), transform(impl, sym)); } @@ -321,17 +343,26 @@ public class LambdaLift extends OwnerTransformer tree, mods, sym.name, addTypeParams(transform(tparams, sym), newtparams), new ValDef[][]{addParams(transform(vparams, sym)[0], newparams)}, - transform(tpe), + transform(tpe, sym), transform(rhs, sym)); liftedDefs.append(tree1); return Tree.Empty; } else { return copy.DefDef( tree, mods, sym.name, - transform(tparams, sym), transform(vparams, sym), transform(tpe), + transform(tparams, sym), transform(vparams, sym), transform(tpe, sym), transform(rhs, sym)); } + case TypeDef(int mods, Name name, TypeDef[] tparams, Tree rhs): + // ignore type definition as owner. + // reason: it might be in a refinement + // todo: handle type parameters? + return copy.TypeDef( + tree, mods, name, + transform(tparams, currentOwner), + transform(rhs, currentOwner)); + case ValDef(int mods, Name name, Tree tpe, Tree rhs): Symbol sym = tree.symbol(); Name name1 = sym.name; @@ -393,8 +424,9 @@ public class LambdaLift extends OwnerTransformer params[i].pos = owner.pos; params[i].flags = PARAM | SYNTHETIC; params[i].setOwner(owner); - params[i].setInfo(freevars[i].type()); } + for (int i = 0; i < params.length; i++) + params[i].setInfo(freevars[i].info().subst(freevars, params)); return params; } diff --git a/sources/scalac/transformer/LambdaLiftPhase.java b/sources/scalac/transformer/LambdaLiftPhase.java index d3ca99b43d..0bfc7f6812 100644 --- a/sources/scalac/transformer/LambdaLiftPhase.java +++ b/sources/scalac/transformer/LambdaLiftPhase.java @@ -43,7 +43,8 @@ public class LambdaLiftPhase extends PhaseDescriptor implements Kinds, Modifiers } public Type transformInfo(Symbol sym, Type tp) { - Type tp1 = transform(tp, sym.owner()); + Type tp1 = tp; + if (sym != Symbol.NONE) tp1 = transform(tp, sym.owner()); if ((sym.flags & Modifiers.CAPTURED) != 0) return refType(tp1); else return tp1; } @@ -74,6 +75,7 @@ public class LambdaLiftPhase extends PhaseDescriptor implements Kinds, Modifiers System.arraycopy(map(targs), 0, targs1, 0, targs.length); while (i < tparams.length) { targs1[i] = proxy(tparams[i], owner).type(); + i++; } return Type.TypeRef(pre, sym, targs1); } @@ -111,7 +113,9 @@ public class LambdaLiftPhase extends PhaseDescriptor implements Kinds, Modifiers if (ownerparams[i].name == fv.name) return ownerparams[i]; } + assert o.owner() != o; o = o.owner(); + } throw new ApplicationError("proxy " + fv + " in " + owner); } diff --git a/sources/scalac/transformer/UnCurryPhase.java b/sources/scalac/transformer/UnCurryPhase.java index cb80db1ee9..8d8ea7c87c 100644 --- a/sources/scalac/transformer/UnCurryPhase.java +++ b/sources/scalac/transformer/UnCurryPhase.java @@ -66,8 +66,6 @@ public class UnCurryPhase extends PhaseDescriptor implements Modifiers { else return Type.MethodType(uncurriedParams, uncurriedTp1); } case PolyType(Symbol[] tparams, Type tp1): - if (tp instanceof Infer.VirtualPolyType) - return uncurry(tp1); switch (tp1) { case MethodType(_, _): Type newtp1 = uncurry(tp1); diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index d4414100bd..b6b7f4906f 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -89,7 +89,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { else if (sym.name.isTypeName()) kind = "class "; else kind = "constructor "; throw new Type.Error("file " + unit.source + " does not define public " + - kind + sym.name); + kind + sym.fullName()); } else { descr.newSources.add(unit); } @@ -247,11 +247,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { * - symbols with `override' modifier override some other symbol. */ void validate(Symbol sym) { - checkNoConflict(sym, ABSTRACT, PRIVATE); + checkNoConflict(sym, DEFERRED, PRIVATE); checkNoConflict(sym, FINAL, PRIVATE); checkNoConflict(sym, PRIVATE, PROTECTED); checkNoConflict(sym, PRIVATE, OVERRIDE); - checkNoConflict(sym, ABSTRACT, FINAL); + checkNoConflict(sym, DEFERRED, FINAL); if ((sym.flags & ABSTRACTCLASS) != 0 && sym.kind != CLASS) { error(sym.pos, "`abstract' modifier can be used only for classes; " + "\nit should be omitted for abstract members"); @@ -262,13 +262,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { if ((sym.flags & DEF) != 0 && sym.owner().isPrimaryConstructor()) { error(sym.pos, "`def' modifier not allowed for class parameters"); } - if ((sym.flags & ABSTRACT) != 0) { + if ((sym.flags & DEFERRED) != 0) { if (sym.owner().kind != CLASS || (sym.owner().flags & MODUL) != 0 || sym.owner().isAnonymousClass()) { error(sym.pos, abstractVarNote(sym, "only classes can have declared but undefined members")); - sym.flags &= ~ABSTRACT; + sym.flags &= ~DEFERRED; } } if ((sym.flags & OVERRIDE) != 0) { @@ -426,7 +426,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { */ void checkNoConflict(Symbol sym, int flag1, int flag2) { if ((sym.flags & (flag1 | flag2)) == (flag1 | flag2)) { - if (flag1 == ABSTRACT) + if (flag1 == DEFERRED) error(sym.pos, "abstract member may not have " + Modifiers.Helper.toString(flag2) + " modifier"); else @@ -507,7 +507,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Symbol member = clazz.info().lookup(other.name); if (other != member && member.kind != NONE) checkOverride(clazz, member, other); - if ((member.flags & ABSTRACT) != 0 && + if ((member.flags & DEFERRED) != 0 && clazz.kind == CLASS && (clazz.flags & ABSTRACTCLASS) == 0) { if (clazz.isAnonymousClass()) @@ -538,7 +538,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { overrideError(pos, member, other, "needs `protected' modifier"); } else if ((other.flags & FINAL) != 0) { overrideError(pos, member, other, "cannot override final member"); - } else if ((other.flags & ABSTRACT) == 0 && ((member.flags & OVERRIDE) == 0)) { + } else if ((other.flags & DEFERRED) == 0 && ((member.flags & OVERRIDE) == 0)) { overrideError(pos, member, other, "needs `override' modifier"); } else { Type self = clazz.thisType(); @@ -651,7 +651,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { return enterSym(tree, new TermSymbol(tree.pos, name, owner, mods)); case TypeDef(int mods, Name name, _, _): - int kind = (mods & (ABSTRACT | PARAM)) != 0 ? TYPE : ALIAS; + int kind = (mods & (DEFERRED | PARAM)) != 0 ? TYPE : ALIAS; TypeSymbol tsym = new TypeSymbol(kind, tree.pos, name, owner, mods); if (kind == ALIAS) tsym.constructor().setInfo(new LazyTreeType(tree)); @@ -793,7 +793,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { if ((sym.owner().flags & ACCESSOR) != 0) { // this is the paremeter of a variable setter method. ((ValDef) tree).tpe = tpe = - gen.mkType(tree.pos, sym.owner().accessed().type()); + gen.mkType(tree.pos, sym.owner().accessed().type().widen()); } else { error(tree.pos, "missing parameter type"); ((ValDef) tree).tpe = tpe = @@ -802,8 +802,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { owntype = tpe.type; } else { ((ValDef) tree).rhs = rhs = transform(rhs, EXPRmode); - owntype = rhs.type; - if ((sym.flags & MUTABLE) != 0) owntype = owntype.widen(); + owntype = rhs.type.widen(); } } else { owntype = transform(tpe, TYPEmode).type; @@ -818,7 +817,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { if (tpe == Tree.Empty) { int rhsmode = name.isConstrName() ? CONSTRmode : EXPRmode; ((DefDef) tree).rhs = rhs = transform(rhs, rhsmode); - restpe = rhs.type; + restpe = rhs.type.widen(); } else { restpe = transform(tpe, TYPEmode).type; } @@ -1054,10 +1053,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { switch (symtype) { case PolyType(Symbol[] tparams, Type restype): symtype = Type.PolyType( - tparams, new Infer.VirtualPolyType(uninst, restype)); + tparams, Type.PolyType(uninst, restype)); break; default: - symtype = new Infer.VirtualPolyType(uninst, symtype); + symtype = Type.PolyType(uninst, symtype); } } if (sym.isTerm() && (sym.flags & MUTABLE) == 0 && symtype.isObjectType() && @@ -1529,7 +1528,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { /** The main attribution function */ public Tree transform(Tree tree) { - if (mode == PATTERNmode) new TextTreePrinter().print("pattern ").print(tree).print(" with pt = ").print(pt.toString()).println().end();//debug Symbol sym = tree.symbol(); if (sym != null && !sym.isInitialized()) sym.initialize(); if (global.debug && TreeInfo.isDefinition(tree)) @@ -1583,7 +1581,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Tree tpe1 = transform(tpe, TYPEmode); Tree rhs1 = rhs; if (tpe1 == Tree.Empty) { - tpe1 = gen.mkType(rhs1.pos, rhs.type); + tpe1 = gen.mkType(rhs1.pos, rhs.type.widen()); // rhs already attributed by defineSym in this case } else if (rhs != Tree.Empty) { rhs1 = transform(rhs1, EXPRmode, sym.type()); @@ -1600,7 +1598,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Tree tpe1 = transform(tpe, TYPEmode); Tree rhs1 = rhs; if (tpe1 == Tree.Empty) { - tpe1 = gen.mkType(rhs1.pos, rhs1.type); + tpe1 = gen.mkType(rhs1.pos, rhs1.type.widen()); // rhs already attributed by defineSym in this case } else if (rhs != Tree.Empty) { rhs1 = transform(rhs, EXPRmode, @@ -1701,7 +1699,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { 0, Names.ANON_CLASS_NAME.toTypeName(), Tree.ExtTypeDef.EMPTY_ARRAY, - Tree.ExtValDef.EMPTY_ARRAY_ARRAY, + new ValDef[][]{Tree.ExtValDef.EMPTY_ARRAY}, Tree.Empty, templ); enterSym(cd); @@ -1732,8 +1730,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Tree alloc = gen.Typed( gen.New( - gen.mkRef(tree.pos, - Type.localThisType, clazz.constructor())), + gen.Apply( + gen.mkRef(tree.pos, + Type.localThisType, clazz.constructor()), + Tree.EMPTY_ARRAY)), tp); popContext(); return make.Block(tree.pos, new Tree[]{cd, alloc}) @@ -1745,7 +1745,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { case Typed(Tree expr, Tree tpe): Tree tpe1 = transform(tpe, TYPEmode); - Tree expr1 = transform(expr, EXPRmode, tpe1.type); + Tree expr1 = transform(expr, mode, tpe1.type); return copy.Typed(tree, expr1, tpe1) .setType(tpe1.type); @@ -1754,7 +1754,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Type restype = desugarize.preFunction(vparams, pt); enterParams(vparams); Tree body1 = transform(body, EXPRmode, restype); - if (!infer.isFullyDefined(restype)) restype = body1.type; + if (!infer.isFullyDefined(restype)) restype = body1.type.widen(); popContext(); Tree tree1 = copy.Function(tree, vparams, body1); Tree tree2 = transform(desugarize.Function(tree1, restype)); @@ -1964,7 +1964,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { case ValDef(_, _, _, _): return error(tree, "recursive " + cyc.sym + " needs type"); case DefDef(_, _, _, _, _, _): - return error(tree, "recursive " + cyc.sym + " needs result type"); + return error(tree, "recursive function " + cyc.sym.name + " needs result type"); } } } diff --git a/sources/scalac/typechecker/DeSugarize.java b/sources/scalac/typechecker/DeSugarize.java index 665e648419..15c5713293 100644 --- a/sources/scalac/typechecker/DeSugarize.java +++ b/sources/scalac/typechecker/DeSugarize.java @@ -424,7 +424,8 @@ public class DeSugarize implements Kinds, Modifiers { Tree.ExtTypeDef.EMPTY_ARRAY, Tree.ExtValDef.EMPTY_ARRAY_ARRAY, tpe, - (rhs == Tree.Empty) ? Tree.Empty : make.Ident(tree.pos, varname)); + ((mods & DEFERRED) != 0) ? Tree.Empty + : make.Ident(tree.pos, varname)); Tree setter = make.DefDef( tree.pos, mods | ACCESSOR, setterName(name), Tree.ExtTypeDef.EMPTY_ARRAY, @@ -432,12 +433,12 @@ public class DeSugarize implements Kinds, Modifiers { (ValDef) make.ValDef( tree.pos, SYNTHETIC, parameterName(0), tpe, Tree.Empty)}}, gen.mkType(tree.pos, global.definitions.UNIT_TYPE), - (rhs == Tree.Empty) ? Tree.Empty + ((mods & DEFERRED) != 0) ? Tree.Empty : make.Assign( tree.pos, make.Ident(tree.pos, varname), make.Ident(tree.pos, parameterName(0)))); - if (rhs == Tree.Empty) return new Tree[]{getter, setter}; + if ((mods & DEFERRED) != 0) return new Tree[]{getter, setter}; else return new Tree[]{vardef1, getter, setter}; default: throw new ApplicationError(); diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java index 8dd769b640..c788a368da 100644 --- a/sources/scalac/typechecker/Infer.java +++ b/sources/scalac/typechecker/Infer.java @@ -99,10 +99,25 @@ public class Infer implements Modifiers, Kinds { return transform(tree); } + Type.Map elimInferredPolyMap = new Type.Map() { + public Type apply(Type t) { + switch (t) { + case PolyType(Symbol[] tparams1, Type restp): + if (tparams1.length == tparams.length && + tparams1[0] == tparams[0]) { + for (int i = 1; i < tparams.length; i++) + assert tparams1[i] == tparams[i]; + return apply(restp); + } + } + return map(t); + } + }; + public Tree transform(Tree tree) { // System.out.println("[" + ArrayApply.toString(targs,"",",","") + "/" + ArrayApply.toString(tparams,"",",","") + "]" + tree + "@" + tree.symbol());//DEBUG if (tree.type == null) return tree; - tree.type = tree.type.subst(tparams, targs); + tree.type = elimInferredPolyMap.apply(tree.type).subst(tparams, targs); switch (tree) { case Ident(Name name): if (name.isTypeName()) { @@ -129,17 +144,6 @@ public class Infer implements Modifiers, Kinds { } } - public static class VirtualPolyType extends Type.PolyType { - VirtualPolyType(Symbol[] tparams, Type result) { - super(tparams, result); - } - public String toString() { - return - ArrayApply.toString(Symbol.defString(tparams), "[ ", ",", " ]") + - result; - } - } - /** map every TypeVar to its constraint.inst field. * throw a NoInstance exception if a NoType or AnyType is encountered. */ @@ -639,7 +643,7 @@ public class Infer implements Modifiers, Kinds { checkBounds(tparams, targs, "inferred "); Type restype1 = (uninstantiated.length == 0) ? restype : Type.MethodType(params, - new VirtualPolyType(uninstantiated, restpe)); + Type.PolyType(uninstantiated, restpe)); return mkTypeApply(tree, tparams, restype1, targs); default: return tree; diff --git a/test/files/pos/test5.scala b/test/files/pos/test5.scala index 4851e5e6a2..850fb49a31 100644 --- a/test/files/pos/test5.scala +++ b/test/files/pos/test5.scala @@ -4,11 +4,11 @@ module test { trait F[If] {} - def f[Jf](h: Jf):F[Jf] = f@[Jf](h); + def f[Jf](h: Jf):F[Jf] = f[Jf](h); trait G[Ig] {} - def g[Jg](h: Jg):G[Jg] = g@[Jg](h); + def g[Jg](h: Jg):G[Jg] = g[Jg](h); class M[P]() { class I[X]() { @@ -24,7 +24,7 @@ module test { // Values with types P and i.X as seen from instances of M def val_mp: P = val_mp; - def val_mix: G[P] = g@[P](val_mp); + def val_mix: G[P] = g[P](val_mp); } class N[Q]() extends M[F[Q]]() { @@ -33,7 +33,7 @@ module test { class J[Y]() extends I[G[Y]]() { // Values with types Y and X as seen from instances of J def val_jy: Y = val_jy; - def val_jx: G[Y] = g@[Y](val_jy); + def val_jx: G[Y] = g[Y](val_jy); // Check type P chk_ip(val_mp); @@ -42,10 +42,10 @@ module test { // Values with types Q, X.P, i.X, j.Y and j.X as seen from instances of N def val_nq: Q = val_nq; - def val_np: F[Q] = f@[Q](val_nq); - def val_nix: G[F[Q]] = g@[F[Q]](val_np); - def val_njy: G[Q] = g@[Q](val_nq); - def val_njx: G[G[Q]] = g@[G[Q]](val_njy); + def val_np: F[Q] = f[Q](val_nq); + def val_nix: G[F[Q]] = g[F[Q]](val_np); + def val_njy: G[Q] = g[Q](val_nq); + def val_njx: G[G[Q]] = g[G[Q]](val_njy); // Check type i.P i.chk_ip(val_mp); diff --git a/test/files/pos/test5refine.scala b/test/files/pos/test5refine.scala index 1097c6cff7..a9d7a02bf6 100644 --- a/test/files/pos/test5refine.scala +++ b/test/files/pos/test5refine.scala @@ -4,11 +4,11 @@ module test { abstract trait F { type If; } - def f[Jf](h: Jf):F with { type If = Jf } = f@[Jf](h); + def f[Jf](h: Jf):F with { type If = Jf } = f[Jf](h); abstract trait G { type Ig; } - def g[Jg](h: Jg):G with { type Ig = Jg } = g@[Jg](h); + def g[Jg](h: Jg):G with { type Ig = Jg } = g[Jg](h); abstract class M() { type P; @@ -27,7 +27,7 @@ module test { // Values with types P and i.X as seen from instances of M def val_mp: P = val_mp; - def val_mix: G with { type Ig = P } = g@[P](val_mp); + def val_mix: G with { type Ig = P } = g[P](val_mp); } abstract class N() extends M() { @@ -40,7 +40,7 @@ module test { type X = G with { type Ig = Y; }; // Values with types Y and X as seen from instances of J def val_jy: Y = val_jy; - def val_jx: G with { type Ig = Y; } = g@[Y](val_jy); + def val_jx: G with { type Ig = Y; } = g[Y](val_jy); // Check type P chk_ip(val_mp); @@ -49,10 +49,10 @@ module test { // Values with types Q, X.P, i.X, j.Y and j.X as seen from instances of N def val_nq: Q = val_nq; - def val_np: F with { type If = Q } = f@[Q](val_nq); - def val_nix: G with { type Ig = F with { type If = Q } } = g@[F with { type If = Q }](val_np); - def val_njy: G with { type Ig = Q; } = g@[Q](val_nq); - def val_njx: G with { type Ig = G with { type Ig = Q }} = g@[G with { type Ig = Q; }](val_njy); + def val_np: F with { type If = Q } = f[Q](val_nq); + def val_nix: G with { type Ig = F with { type If = Q } } = g[F with { type If = Q }](val_np); + def val_njy: G with { type Ig = Q; } = g[Q](val_nq); + def val_njx: G with { type Ig = G with { type Ig = Q }} = g[G with { type Ig = Q; }](val_njy); // Check type i.P i.chk_ip(val_mp); diff --git a/test/pos/test5.scala b/test/pos/test5.scala index 4851e5e6a2..850fb49a31 100644 --- a/test/pos/test5.scala +++ b/test/pos/test5.scala @@ -4,11 +4,11 @@ module test { trait F[If] {} - def f[Jf](h: Jf):F[Jf] = f@[Jf](h); + def f[Jf](h: Jf):F[Jf] = f[Jf](h); trait G[Ig] {} - def g[Jg](h: Jg):G[Jg] = g@[Jg](h); + def g[Jg](h: Jg):G[Jg] = g[Jg](h); class M[P]() { class I[X]() { @@ -24,7 +24,7 @@ module test { // Values with types P and i.X as seen from instances of M def val_mp: P = val_mp; - def val_mix: G[P] = g@[P](val_mp); + def val_mix: G[P] = g[P](val_mp); } class N[Q]() extends M[F[Q]]() { @@ -33,7 +33,7 @@ module test { class J[Y]() extends I[G[Y]]() { // Values with types Y and X as seen from instances of J def val_jy: Y = val_jy; - def val_jx: G[Y] = g@[Y](val_jy); + def val_jx: G[Y] = g[Y](val_jy); // Check type P chk_ip(val_mp); @@ -42,10 +42,10 @@ module test { // Values with types Q, X.P, i.X, j.Y and j.X as seen from instances of N def val_nq: Q = val_nq; - def val_np: F[Q] = f@[Q](val_nq); - def val_nix: G[F[Q]] = g@[F[Q]](val_np); - def val_njy: G[Q] = g@[Q](val_nq); - def val_njx: G[G[Q]] = g@[G[Q]](val_njy); + def val_np: F[Q] = f[Q](val_nq); + def val_nix: G[F[Q]] = g[F[Q]](val_np); + def val_njy: G[Q] = g[Q](val_nq); + def val_njx: G[G[Q]] = g[G[Q]](val_njy); // Check type i.P i.chk_ip(val_mp); diff --git a/test/pos/test5refine.scala b/test/pos/test5refine.scala index 1097c6cff7..a9d7a02bf6 100644 --- a/test/pos/test5refine.scala +++ b/test/pos/test5refine.scala @@ -4,11 +4,11 @@ module test { abstract trait F { type If; } - def f[Jf](h: Jf):F with { type If = Jf } = f@[Jf](h); + def f[Jf](h: Jf):F with { type If = Jf } = f[Jf](h); abstract trait G { type Ig; } - def g[Jg](h: Jg):G with { type Ig = Jg } = g@[Jg](h); + def g[Jg](h: Jg):G with { type Ig = Jg } = g[Jg](h); abstract class M() { type P; @@ -27,7 +27,7 @@ module test { // Values with types P and i.X as seen from instances of M def val_mp: P = val_mp; - def val_mix: G with { type Ig = P } = g@[P](val_mp); + def val_mix: G with { type Ig = P } = g[P](val_mp); } abstract class N() extends M() { @@ -40,7 +40,7 @@ module test { type X = G with { type Ig = Y; }; // Values with types Y and X as seen from instances of J def val_jy: Y = val_jy; - def val_jx: G with { type Ig = Y; } = g@[Y](val_jy); + def val_jx: G with { type Ig = Y; } = g[Y](val_jy); // Check type P chk_ip(val_mp); @@ -49,10 +49,10 @@ module test { // Values with types Q, X.P, i.X, j.Y and j.X as seen from instances of N def val_nq: Q = val_nq; - def val_np: F with { type If = Q } = f@[Q](val_nq); - def val_nix: G with { type Ig = F with { type If = Q } } = g@[F with { type If = Q }](val_np); - def val_njy: G with { type Ig = Q; } = g@[Q](val_nq); - def val_njx: G with { type Ig = G with { type Ig = Q }} = g@[G with { type Ig = Q; }](val_njy); + def val_np: F with { type If = Q } = f[Q](val_nq); + def val_nix: G with { type Ig = F with { type If = Q } } = g[F with { type If = Q }](val_np); + def val_njy: G with { type Ig = Q; } = g[Q](val_nq); + def val_njx: G with { type Ig = G with { type Ig = Q }} = g[G with { type Ig = Q; }](val_njy); // Check type i.P i.chk_ip(val_mp); |