diff options
-rw-r--r-- | sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala | 4 | ||||
-rw-r--r-- | sources/scala/tools/scalac/typechecker/Analyzer.scala | 2 | ||||
-rwxr-xr-x | sources/scala/tools/scalac/typechecker/RefCheck.scala | 7 | ||||
-rw-r--r-- | sources/scalac/symtab/Modifiers.java | 3 | ||||
-rw-r--r-- | sources/scalac/symtab/Symbol.java | 7 | ||||
-rw-r--r-- | sources/scalac/symtab/Type.java | 12 | ||||
-rw-r--r-- | sources/scalac/transformer/LambdaLift.java | 4 |
7 files changed, 32 insertions, 7 deletions
diff --git a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala b/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala index 09acf7870b..08d921ac73 100644 --- a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala +++ b/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala @@ -157,6 +157,7 @@ class TextTreePrinter(writer: PrintWriter) with TreePrinter { protected final val TXT_NULL = Simple("<null>"); protected final val TXT_OBJECT_COMMENT = Simple("/*object*/ "); protected final val TXT_EMPTY = Simple("<empty>"); + protected final val TXT_TEMPLATE = Simple("<template>"); protected final val TXT_QUOTE = Simple("\""); protected final val TXT_PLUS = Simple("+"); @@ -330,6 +331,9 @@ class TextTreePrinter(writer: PrintWriter) with TreePrinter { } print(TXT_RIGHT_BRACE); + case templ @ Tree$Template(bases, body) => + printTemplate(tree.symbol().owner(), TXT_TEMPLATE , templ, false); + case Tree$CaseDef(pat, guard, body) => print(KW_CASE); print(Space); diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala index 8c9fe6f21d..690805fbe4 100644 --- a/sources/scala/tools/scalac/typechecker/Analyzer.scala +++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala @@ -2118,8 +2118,6 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( this.pt = pt; val tree1: Tree = adapt(transform(tree), mode, pt); - assert(tree.getType() != Type.AnyType, tree);//debug - //new TextTreePrinter().print(tree1).print(": " + tree1.getType()).println().end();//DEBUG this.mode = savedMode; diff --git a/sources/scala/tools/scalac/typechecker/RefCheck.scala b/sources/scala/tools/scalac/typechecker/RefCheck.scala index b1cea2608d..8c421dddc7 100755 --- a/sources/scala/tools/scalac/typechecker/RefCheck.scala +++ b/sources/scala/tools/scalac/typechecker/RefCheck.scala @@ -1028,7 +1028,7 @@ class RefCheck(globl: scalac.Global) extends Transformer(globl) { transform(tree) } - override def transform(tree: Tree): Tree = { + override def transform(tree: Tree): Tree = try { val sym = tree.symbol(); tree match { case Tree.Empty => @@ -1160,6 +1160,11 @@ class RefCheck(globl: scalac.Global) extends Transformer(globl) { case _ => elimTypeNode(super.transform(tree)) } + } catch { + case ex: Type$Error => + if (global.debug) ex.printStackTrace(); + unit.error(tree.pos, ex.msg); + tree } override def transform(trees: Array[Tree]): Array[Tree] = diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java index 173eda4e61..ab222e723f 100644 --- a/sources/scalac/symtab/Modifiers.java +++ b/sources/scalac/symtab/Modifiers.java @@ -48,6 +48,9 @@ public interface Modifiers { int INCONSTRUCTOR = 0x01000000; // transient flag for Analyzer int PARAMACCESSOR = 0x02000000; // for methods: is an access method for a val parameter // for parameters: is a val parameter + int CLOSURELOCK = PARAMACCESSOR; + // secondary meaning: a lock to test that closures of type + // symbols are non-cyclic. int ACCESSOR = 0x04000000; // function is an access function for a // value or variable diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index d2bbd8f8b7..3390eb7a26 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -1970,7 +1970,12 @@ abstract class TypeSymbol extends Symbol { */ public final Type[] closure() { if (kind == ALIAS) return info().symbol().closure(); - return (Type[])closures.getValue(this); + if ((flags & CLOSURELOCK) != 0 && Global.instance.currentPhase.id <= Global.instance.PHASE.REFCHECK.id()) + throw new Type.Error("illegal cyclic reference involving " + this); + flags |= CLOSURELOCK; + Type[] result = (Type[])closures.getValue(this); + flags &= ~CLOSURELOCK; + return result; } public void reset(Type completer) { diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 3c260d93b7..2b2044a872 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -215,8 +215,14 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { throw new Type.Malformed(pre, sym.nameString()); if (sym.isTypeAlias()) { Symbol[] params = sym.typeParams(); - if (args.length == params.length) - return pre.memberInfo(sym).subst(params, args); + if (args.length == params.length) { + if (sym.isLocked()) throw new Type.Error( + "illegal cyclic reference involving " + sym); + sym.flags |= LOCKED; + Type result = pre.memberInfo(sym).subst(params, args); + sym.flags &= ~LOCKED; + return result; + } assert args.length == 0 || args.length == params.length: Debug.show(pre, sym, args, params); } @@ -2690,7 +2696,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { /** Return the least upper bound of non-empty array of types `tps'. */ public static Type lub0(Type[] tps) { - //System.out.println("lub" + ArrayApply.toString(tps));//DEBUG + //for (int i = 0; i < recCount; i++) System.out.print(" "); System.out.println("lub" + ArrayApply.toString(tps));//debug if (tps.length == 0) return Global.instance.definitions.ALL_TYPE(); diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java index 5cb2d52117..d6247af62b 100644 --- a/sources/scalac/transformer/LambdaLift.java +++ b/sources/scalac/transformer/LambdaLift.java @@ -441,6 +441,10 @@ public class LambdaLift extends OwnerTransformer return tree1; */ + case Return(Block(Tree[] stats, Tree value)): + return transform( + gen.Block(stats, gen.Return(tree.pos, tree.symbol(), value))); + case Return(Tree expr): if (tree.symbol() != currentOwner.enclMethod()) { unit.error(tree.pos, "non-local return not yet implemented"); |