diff options
-rw-r--r-- | sources/scalac/symtab/Symbol.java | 3 | ||||
-rw-r--r-- | sources/scalac/symtab/Type.java | 65 | ||||
-rw-r--r-- | sources/scalac/typechecker/Analyzer.java | 11 | ||||
-rw-r--r-- | test/files/neg/constrparams.scala | 6 | ||||
-rw-r--r-- | test/files/pos/aliases.scala | 21 | ||||
-rw-r--r-- | test/files/pos/null.scala | 3 | ||||
-rw-r--r-- | test/neg/constrparams.scala | 6 | ||||
-rw-r--r-- | test/pos/aliases.scala | 21 | ||||
-rw-r--r-- | test/pos/null.scala | 3 |
9 files changed, 106 insertions, 33 deletions
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index 3290821b79..c1183c9aed 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -156,7 +156,8 @@ public abstract class Symbol implements Modifiers, Kinds { public final boolean isStable() { return kind == VAL && ((flags & STABLE) != 0 || - (flags & MUTABLE) == 0 && type().isObjectType()); + (flags & MUTABLE) == 0 && type().isObjectType()) && + !owner.isPrimaryConstructor(); } /** Does this symbol denote a variable? */ diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index abaa4f23ad..28b6b59a4b 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -136,13 +136,27 @@ public class Type implements Modifiers, Kinds, TypeTags { ExtSingleType(Type pre, Symbol sym) { super(pre, sym); } - public Type widen() { + private Type type() { if (definedId != Global.instance.currentPhase.id) { definedId = Global.instance.currentPhase.id; - tp = pre.memberType(sym).resultType().widen(); + tp = pre.memberType(sym).resultType(); } return tp; } + /** If this type is a thistype or singleton type, its underlying object type, + * otherwise the type itself. + */ + public Type widen() { + return type().widen(); + } + /** If this type is a singleton type whose type is another, the end of the chain, + * otherwise the type itself. + */ + public Type aliasedType() { + Type tp = type(); + if (tp.isStable()) return tp.aliasedType(); + else return this; + } } static class ExtCompoundType extends CompoundType { @@ -222,6 +236,13 @@ public class Type implements Modifiers, Kinds, TypeTags { return tps1; } + /** If this type is a singleton type whose type is another, the end of the chain, + * otherwise the type itself. + */ + public Type aliasedType() { + return this; + } + /** The thistype or singleton type corresponding to values of this type. */ public Type narrow() { @@ -1197,25 +1218,12 @@ public class Type implements Modifiers, Kinds, TypeTags { case NoType: return false; - case ThisType(Symbol sym1): - switch (this) { - case ThisType(Symbol sym): - return sym == sym1; - case SingleType(Type pre, Symbol sym): - return sym.isModule() - && sym.moduleClass() == sym1 - && pre.isSameAs(sym1.owner().thisType()); - } - break; - - case SingleType(Type pre1, Symbol sym1): + case ThisType(_): + case SingleType(_, _): switch (this) { - case SingleType(Type pre, Symbol sym): - return sym == sym1 && pre.isSameAs(pre1); - case ThisType(Symbol sym): - return sym1.isModule() - && sym == sym1.moduleClass() - && sym.owner().thisType().isSameAs(pre1); + case ThisType(_): + case SingleType(_, _): + return this.isSameAs(that); } break; @@ -1445,20 +1453,27 @@ public class Type implements Modifiers, Kinds, TypeTags { case SingleType(Type pre1, Symbol sym1): return sym1.isModule() && sym == sym1.moduleClass() - && sym.owner().thisType().isSameAs(pre1); + && sym.owner().thisType().isSameAs(pre1) + || + that != that.aliasedType() && + this.isSameAs(that.aliasedType()); } break; case SingleType(Type pre, Symbol sym): switch (that) { case SingleType(Type pre1, Symbol sym1): - return sym == sym1 && pre.isSameAs(pre1); - //|| sym.type.isStable() && sym.type.isSameAs(that) - //|| sym1.type.isStable() && this.isSameAs(sym1.type); + return sym == sym1 && pre.isSameAs(pre1) + || + (this != this.aliasedType() || that != that.aliasedType()) && + this.aliasedType().isSameAs(that.aliasedType()); case ThisType(Symbol sym1): return sym.isModule() && sym.moduleClass() == sym1 - && pre.isSameAs(sym1.owner().thisType()); + && pre.isSameAs(sym1.owner().thisType()) + || + this != this.aliasedType() && + this.aliasedType().isSameAs(that); } break; diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 0648a5d1de..db3e09f50c 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -527,8 +527,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { */ Tree checkStable(Tree tree) { if (TreeInfo.isPureExpr(tree) || tree.type == Type.ErrorType) return tree; - new TextTreePrinter().print(tree).end();//debug - System.out.println(" " + tree.type);//debug + //new TextTreePrinter().print(tree).end();//DEBUG + //System.out.println(" " + tree.type);//DEBUG return error(tree, "stable identifier required"); } @@ -822,8 +822,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { sym.constructor().flags |= INITIALIZED; if (tpe != Tree.Empty) - sym.setTypeOfThis( - checkNoEscape(tpe.pos, transform(tpe, TYPEmode).type)); + sym.setTypeOfThis(transform(tpe, TYPEmode).type); defineTemplate(templ, sym); owntype = templ.type; @@ -1664,8 +1663,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Tree.ValDef[][] vparams1 = transform(vparams); Tree tpe1 = transform(tpe); Tree.Template templ1 = transformTemplate(templ, sym); - for (int i = 0; i < templ1.parents.length; i++) - checkNoEscape(templ1.parents[i].pos, templ1.parents[i].type); if ((sym.flags & ABSTRACTCLASS) == 0 && !sym.type().isSubType(sym.typeOfThis())) @@ -2025,7 +2022,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { return tree; case SingletonType(Tree ref): - Tree ref1 = transform(ref, EXPRmode, Type.AnyType); + Tree ref1 = transform(ref, EXPRmode | QUALmode, Type.AnyType); return make.TypeTerm(tree.pos) .setType(checkObjectType(tree.pos, ref1.type.resultType())); diff --git a/test/files/neg/constrparams.scala b/test/files/neg/constrparams.scala new file mode 100644 index 0000000000..f6b037b312 --- /dev/null +++ b/test/files/neg/constrparams.scala @@ -0,0 +1,6 @@ +abstract class C(x: C) { + type t; + private val y: x.type = x; + private val z: x.t = null; //error +} + diff --git a/test/files/pos/aliases.scala b/test/files/pos/aliases.scala new file mode 100644 index 0000000000..bcca90d99d --- /dev/null +++ b/test/files/pos/aliases.scala @@ -0,0 +1,21 @@ +abstract class C() { + + type t <: C; + + val x: t; + val y: x.type; + val z: x.type; + + val xt: x.t; + val yt: y.t; + val zt: z.t; + + def fx(a: x.t): Unit; + def fy(a: y.t): Unit; + def fz(a: z.t): Unit; + + fx(xt); fx(yt); fx(zt); + fy(xt); fy(yt); fy(zt); + fz(xt); fz(yt); fz(zt); + +} diff --git a/test/files/pos/null.scala b/test/files/pos/null.scala new file mode 100644 index 0000000000..54a2c0f995 --- /dev/null +++ b/test/files/pos/null.scala @@ -0,0 +1,3 @@ +module M { + val x: Boolean = null == null; +}
\ No newline at end of file diff --git a/test/neg/constrparams.scala b/test/neg/constrparams.scala new file mode 100644 index 0000000000..f6b037b312 --- /dev/null +++ b/test/neg/constrparams.scala @@ -0,0 +1,6 @@ +abstract class C(x: C) { + type t; + private val y: x.type = x; + private val z: x.t = null; //error +} + diff --git a/test/pos/aliases.scala b/test/pos/aliases.scala new file mode 100644 index 0000000000..bcca90d99d --- /dev/null +++ b/test/pos/aliases.scala @@ -0,0 +1,21 @@ +abstract class C() { + + type t <: C; + + val x: t; + val y: x.type; + val z: x.type; + + val xt: x.t; + val yt: y.t; + val zt: z.t; + + def fx(a: x.t): Unit; + def fy(a: y.t): Unit; + def fz(a: z.t): Unit; + + fx(xt); fx(yt); fx(zt); + fy(xt); fy(yt); fy(zt); + fz(xt); fz(yt); fz(zt); + +} diff --git a/test/pos/null.scala b/test/pos/null.scala new file mode 100644 index 0000000000..54a2c0f995 --- /dev/null +++ b/test/pos/null.scala @@ -0,0 +1,3 @@ +module M { + val x: Boolean = null == null; +}
\ No newline at end of file |