summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/reference/ScalaReference.tex19
-rw-r--r--sources/scalac/ast/parser/Parser.java4
-rw-r--r--sources/scalac/symtab/Modifiers.java1
-rw-r--r--sources/scalac/symtab/Symbol.java4
-rw-r--r--sources/scalac/symtab/Type.java20
-rw-r--r--sources/scalac/typechecker/RefCheck.java31
-rw-r--r--test/files/pos/bug173.scala5
-rw-r--r--test/pos/bug173.scala5
8 files changed, 38 insertions, 51 deletions
diff --git a/doc/reference/ScalaReference.tex b/doc/reference/ScalaReference.tex
index b0b076358e..109e8cb8d8 100644
--- a/doc/reference/ScalaReference.tex
+++ b/doc/reference/ScalaReference.tex
@@ -1763,12 +1763,13 @@ words \code{this} and
which contains the access.
\item
The \code{override} modifier applies to class member definitions. It
-is mandatory for member definitions that override some other
-non-abstract member definition in a super- or mixin-class. If an
-\code{override} modifier is given, there must be at least one
-overridden member definition. Furthermore, at least one overridden
-definition must be concrete (\sref{sec:members}), unless the class
-containing the overriding member is abstract.
+is mandatory for member definitions that override some other concrete
+member definition in a super- or mixin-class. If an \code{override}
+modifier is given, there must be at least one overridden member
+definition. Furthermore, if the class containing the overriding
+member is not abstract, and one of the overridden definitions is a
+member of its superclass, that definition must be concrete
+(\sref{sec:members}).
\item
The \code{abstract} modifier is used in class definitions. It is
mandatory if the class has abstract members, or if the class has
@@ -1984,7 +1985,7 @@ $x$ that defines $x$ to be an alias of the parameter.
Every case class implicitly overrides some method definitions of class
\lstinline@scala.Object@ (\sref{sec:cls-object}) unless a definition of the same
-method is already given in the case class itself or a non-abstract
+method is already given in the case class itself or a concrete
definition of the same method is given in some base class of the case
class different from \code{Object}. In particular:
\begin{itemize}
@@ -2283,7 +2284,9 @@ argument $x$ is also the ``null'' object.
\item
\lstinline@isInstanceOf[$T\,$]@ always returns \code{false}.
\item
-\lstinline@asInstanceOf[$T\,$]@ always returns the ``null'' object itself.
+\lstinline@asInstanceOf[$T\,$]@ returns the ``null'' object itself if
+$T$ conforms to \lstinline@scala.AnyRef@, and throws a
+\lstinline@NullPointerExcetpion@ otherwise.
\item
\code{toString()} returns the string ``null''.
\end{itemize}
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java
index 4f4b47a416..00128c52fb 100644
--- a/sources/scalac/ast/parser/Parser.java
+++ b/sources/scalac/ast/parser/Parser.java
@@ -2026,13 +2026,13 @@ public class Parser implements Tokens {
} else if (isDefIntro()) {
stats.append(defOrDcl(0));
accept(SEMI);
- if (s.token == RBRACE) {
+ if (s.token == RBRACE || s.token == CASE) {
stats.append(make.Block(s.pos, Tree.EMPTY_ARRAY));
}
} else if (isLocalModifier()) {
stats.append(clsDef(localClassModifiers()));
accept(SEMI);
- if (s.token == RBRACE) {
+ if (s.token == RBRACE || s.token == CASE) {
stats.append(make.Block(s.pos, Tree.EMPTY_ARRAY));
}
} else if (s.token == SEMI) {
diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java
index 78c7e81214..cc9111887a 100644
--- a/sources/scalac/symtab/Modifiers.java
+++ b/sources/scalac/symtab/Modifiers.java
@@ -64,6 +64,7 @@ public interface Modifiers {
int SOURCEFLAGS = 0x00000077 | DEF | REPEATED | MODUL | MUTABLE | PACKAGE | PARAM | TRAIT | COVARIANT | CONTRAVARIANT; // these modifiers can be set in source programs.
int ACCESSFLAGS = PRIVATE | PROTECTED;
int VARIANCES = COVARIANT | CONTRAVARIANT;
+ int CONSTRFLAGS = ACCESSFLAGS | CASE | JAVA | STATIC;
public static class Helper {
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index 11232638d3..4b710248c6 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -1388,7 +1388,7 @@ public abstract class TypeSymbol extends Symbol {
public TypeSymbol(int kind, int pos, Name name, Symbol owner, int flags) {
super(kind, pos, name, owner, flags);
assert name.isTypeName() : this;
- this.constructor = TermSymbol.newConstructor(this, flags & ~MODUL);
+ this.constructor = TermSymbol.newConstructor(this, flags & CONSTRFLAGS);
}
protected void update(int pos, int flags) {
@@ -1443,7 +1443,7 @@ public abstract class TypeSymbol extends Symbol {
/** add a constructor
*/
public Symbol addConstructor() {
- Symbol constr = TermSymbol.newConstructor(this, flags & ~MODUL);
+ Symbol constr = TermSymbol.newConstructor(this, flags & CONSTRFLAGS);
constructor = constructor.overloadWith(constr);
return constr;
}
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index e9e4d3b024..fac8f18f48 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -6,7 +6,7 @@
** $Id$
\* */
//todo: T {} == T
-
+//todo: ELiminate phase dependency in AsSeenFromMap
package scalac.symtab;
@@ -997,12 +997,14 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
* or `sym' itself if none exists.
*/
public Symbol rebind(Symbol sym) {
- Symbol sym1 = lookupNonPrivate(sym.name);
- if (sym1.kind != NONE) {
- if ((sym1.flags & LOCKED) != 0)
- throw new Type.Error("illegal cyclic reference involving " + sym1);
- //System.out.println("rebinding " + sym + " to " + sym1);//DEBUG
- return sym1;
+ if ((sym.flags & (PRIVATE | MODUL)) == 0) {
+ Symbol sym1 = lookupNonPrivate(sym.name);
+ if (sym1.kind != NONE) {
+ if ((sym1.flags & LOCKED) != 0)
+ throw new Type.Error("illegal cyclic reference involving " + sym1);
+ //System.out.println("rebinding " + sym + " to " + sym1);//DEBUG
+ return sym1;
+ }
}
return sym;
}
@@ -1042,7 +1044,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
Type prefix1 = apply(prefix);
Type[] args1 = map(args);
if (prefix1 == prefix && args1 == args) return t;
- Symbol sym1 = (sym.flags & MODUL) == 0 ? prefix1.rebind(sym) : sym;
+ Symbol sym1 = prefix1.rebind(sym);
if (local && sym != sym1) {
// Here what we should do is remove the outer
// type links of sym from args and then add
@@ -1110,7 +1112,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
}
/** This type as seen from prefix `pre' and class `clazz'. This means:
- * Replace all thistypes of `clazz' or one of its superclasses by `pre'
+ * Replace all thistypes of `clazz' or one of its subclasses by `pre'
* and instantiate all parameters by arguments of `pre'.
* Proceed analogously for thistypes referring to outer classes.
*/
diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java
index 5178c3b703..799de7a290 100644
--- a/sources/scalac/typechecker/RefCheck.java
+++ b/sources/scalac/typechecker/RefCheck.java
@@ -64,11 +64,10 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
*/
void checkAllOverrides(int pos, Symbol clazz) {
Type[] closure = clazz.closure();
- HashMap/*<Symbol,Symbol>*/ overrides = new HashMap();
for (int i = 0; i < closure.length; i++) {
for (Scope.SymbolIterator it = closure[i].members().iterator(true);
it.hasNext();) {
- checkOverride(pos, clazz, it.next(), overrides);
+ checkOverride(pos, clazz, it.next());
}
}
@@ -83,24 +82,20 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
if (i < 0) {
unit.error(sym.pos, sym + " overrides nothing");
sym.flags &= ~OVERRIDE;
+ } else if (clazz.kind == CLASS &&
+ (clazz.flags & ABSTRACTCLASS) == 0) {
+ Symbol sup = sym.overriddenSymbol(parents[0]);
+ if (sup.kind != NONE && (sup.flags & DEFERRED) != 0) {
+ abstractClassError(
+ clazz, sym + sym.locationString() +
+ " is marked `override', but overrides an abstract member of the superclass " + parents[0]);
+ }
}
}
}
-
- for (Iterator/*<Symbol>*/ it = overrides.keySet().iterator();
- it.hasNext();) {
- Symbol member = (Symbol) it.next();
- Symbol other = (Symbol) overrides.get(member);
- if ((other.flags & DEFERRED) != 0) {
- abstractClassError(
- clazz, member + member.locationString() +
- " is marked `override' and overrides only abstract members" + other + other.locationString());
- }
- }
}
- void checkOverride(int pos, Symbol clazz, Symbol other,
- HashMap/*<Symbol,Symbol>*/ overrides) {
+ void checkOverride(int pos, Symbol clazz, Symbol other) {
Symbol member = other;
if ((other.flags & PRIVATE) == 0) {
Symbol member1 = clazz.info().lookup(other.name);
@@ -146,11 +141,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
member + member.locationString() + " is not defined" +
(((member.flags & MUTABLE) == 0) ? ""
: "\n(Note that variables need to be initialized to be defined)"));
- } else if (member != other &&
- (member.flags & OVERRIDE) != 0 &&
- ((other.flags & DEFERRED) == 0 ||
- overrides.get(member) == null))
- overrides.put(member, other);
+ }
}
}
//where
diff --git a/test/files/pos/bug173.scala b/test/files/pos/bug173.scala
deleted file mode 100644
index 69f964aa36..0000000000
--- a/test/files/pos/bug173.scala
+++ /dev/null
@@ -1,5 +0,0 @@
-object V with Executable {
- def foo[A](x: String) = new Object;
- def foo[A](x: Runnable) = new Object;
- val code = foo[Int]("test");
-}
diff --git a/test/pos/bug173.scala b/test/pos/bug173.scala
deleted file mode 100644
index 69f964aa36..0000000000
--- a/test/pos/bug173.scala
+++ /dev/null
@@ -1,5 +0,0 @@
-object V with Executable {
- def foo[A](x: String) = new Object;
- def foo[A](x: Runnable) = new Object;
- val code = foo[Int]("test");
-}