summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sources/scalac/symtab/Symbol.java3
-rw-r--r--sources/scalac/symtab/Type.java65
-rw-r--r--sources/scalac/typechecker/Analyzer.java11
-rw-r--r--test/files/neg/constrparams.scala6
-rw-r--r--test/files/pos/aliases.scala21
-rw-r--r--test/files/pos/null.scala3
-rw-r--r--test/neg/constrparams.scala6
-rw-r--r--test/pos/aliases.scala21
-rw-r--r--test/pos/null.scala3
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