summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sources/scala/Predef.scala5
-rw-r--r--sources/scala/Stream.scala67
-rw-r--r--sources/scalac/Global.java11
-rw-r--r--sources/scalac/PhaseRepository.java6
-rw-r--r--sources/scalac/ast/TreeInfo.java9
-rw-r--r--sources/scalac/ast/parser/Parser.java129
-rw-r--r--sources/scalac/ast/printer/TextTreePrinter.java11
-rw-r--r--sources/scalac/symtab/Modifiers.java4
-rw-r--r--sources/scalac/symtab/NameMangler.java14
-rw-r--r--sources/scalac/symtab/SymSet.java24
-rw-r--r--sources/scalac/symtab/Symbol.java14
-rw-r--r--sources/scalac/symtab/Type.java4
-rw-r--r--sources/scalac/symtab/classfile/ClassfileParser.java6
-rw-r--r--sources/scalac/transformer/AddInterfaces.java2
-rw-r--r--sources/scalac/transformer/ExpandMixins.java2
-rw-r--r--sources/scalac/transformer/LambdaLift.java50
-rw-r--r--sources/scalac/transformer/LambdaLiftPhase.java6
-rw-r--r--sources/scalac/transformer/UnCurryPhase.java2
-rw-r--r--sources/scalac/typechecker/Analyzer.java48
-rw-r--r--sources/scalac/typechecker/DeSugarize.java7
-rw-r--r--sources/scalac/typechecker/Infer.java30
-rw-r--r--test/files/pos/test5.scala16
-rw-r--r--test/files/pos/test5refine.scala16
-rw-r--r--test/pos/test5.scala16
-rw-r--r--test/pos/test5refine.scala16
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);