summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/reference/ScalaReference.tex45
-rw-r--r--sources/scala/collection/mutable/HashSet.scala2
-rw-r--r--sources/scala/collection/mutable/SetWrapper.scala2
-rw-r--r--sources/scalac/ast/TreeGen.java2
-rw-r--r--sources/scalac/symtab/Definitions.java4
-rw-r--r--sources/scalac/symtab/Modifiers.java1
-rw-r--r--sources/scalac/symtab/Symbol.java11
-rw-r--r--sources/scalac/symtab/Type.java6
-rw-r--r--sources/scalac/symtab/classfile/JavaTypeCreator.java8
-rw-r--r--sources/scalac/typechecker/Analyzer.java79
-rw-r--r--sources/scalac/typechecker/RefCheck.java71
-rw-r--r--test/files/neg/bug25.check2
-rw-r--r--test/neg/bug25.check2
13 files changed, 170 insertions, 65 deletions
diff --git a/doc/reference/ScalaReference.tex b/doc/reference/ScalaReference.tex
index bee684971a..5d44c69411 100644
--- a/doc/reference/ScalaReference.tex
+++ b/doc/reference/ScalaReference.tex
@@ -2253,7 +2253,7 @@ by the type, then the number is converted to type $\proto$ and the
expression's type is $\proto$. A floating point literal denotes a
single-precision or double precision IEEE floating point number. A
character literal denotes a Unicode character. A string literal
-denotes a member of \lstinline@java.lang.String@.
+denotes a member of \lstinline@scala.Predef.String@.
A symbol literal ~\lstinline@'$x$@~ is a shorthand for the expression
~\lstinline@scala.Symbol("$x$")@. If the symbol literal is followed by an
@@ -2292,7 +2292,7 @@ argument $x$ is also the ``null'' object.
\code{toString()} returns the string ``null''.
\end{itemize}
A reference to any other member of the \code{null} object causes a
-\code{NullPointerException} to be thrown.
+\code{scala.Predef.NullPointerException} to be thrown.
\section{Designators}
\label{sec:designators}
@@ -3072,7 +3072,41 @@ The code above makes use of the fact that \code{map}, \code{flatmap},
\code{filter}, and \code{foreach} are defined for members of class
\lstinline@scala.Array@.
-\section{Try Expressions}
+\section{Return Expressions}
+
+\syntax\begin{lstlisting}
+ Expr ::= return [Expr]
+\end{lstlisting}
+
+A return expression ~\lstinline@return $e$@~ must occur inside the
+body of some enclosing named method or function $f$. This function
+must have an explicitly declared result type, and the type of $e$ must
+conform to it. The return expression evaluates the expression $e$ and
+returns its value as the result of $f$ \nyi{Returns from anonymous
+functions and def parameters are}. The evaluation of any statements or
+expressions following the return expression is omitted. The type of
+a return expression is \code{scala.All}.
+
+
+
+\section{Throw Expressions}
+
+\syntax\begin{lstlisting}
+ Expr ::= throw Expr
+\end{lstlisting}
+
+A throw expression ~\lstinline@throw $e$@~ evaluates the expression
+$e$. The type of this expression must conform to
+\code{scala.Predef.Throwable}@. If $e$ evaluates to an exception
+reference, evaluation is aborted with the thrown exception. If $e$
+evaluates to \code{null}, evaluation is instead aborted with a
+\code{scala.Predef.NullPointerException}. If there is an active
+\code{try} expression (\sref{sec:try}) which handles the thrown
+exception, evaluation resumes with the handler; otherwise the thread
+executing the \code{throw} is aborted. The type of a throw expression
+is \code{scala.All}.
+
+\section{Try Expressions}\label{sec:try}
\syntax\begin{lstlisting}
Expr ::= try `{' block `}' [catch Expr] [finally Expr]
@@ -3108,6 +3142,9 @@ type \code{unit}.
A try expression ~\lstinline@try { $b$ } catch $e_1$ finally $e_2$@~ is a shorthand
for ~\lstinline@try { try { $b$ } catch $e_1$ } finally $e_2$@.
+
+
+
\section{Anonymous Functions}
\label{sec:closures}
@@ -4373,7 +4410,7 @@ underlying run-time system. We postulate a predefined
class \code{Thread} for run-time threads,
\code{fork} function to spawn off a new thread,
as well as \code{Monitor} and \code{Signal} classes. These are
-specified as follows\nyi{Concurrentcy constructs are}.
+specified as follows\nyi{Concurrency constructs are}.
\begin{lstlisting}
diff --git a/sources/scala/collection/mutable/HashSet.scala b/sources/scala/collection/mutable/HashSet.scala
index 9134ca9524..07cc6726c6 100644
--- a/sources/scala/collection/mutable/HashSet.scala
+++ b/sources/scala/collection/mutable/HashSet.scala
@@ -31,7 +31,7 @@ class HashSet[A] extends scala.collection.mutable.Set[A] with HashTable[A] {
def elements = entries;
- override def clear = {
+ def clear = {
initTable(table);
tableSize = 0;
}
diff --git a/sources/scala/collection/mutable/SetWrapper.scala b/sources/scala/collection/mutable/SetWrapper.scala
index f8f53a8a32..920035542b 100644
--- a/sources/scala/collection/mutable/SetWrapper.scala
+++ b/sources/scala/collection/mutable/SetWrapper.scala
@@ -34,7 +34,7 @@ class SetWrapper[A](set: Set[A]) extends Set[A]
override def intersect(that: Set[A]): Unit = set.intersect(that);
- override def clear: Unit = set.clear;
+ def clear: Unit = set.clear;
override def filter(p: A => Boolean): Unit = set.filter(p);
}
diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java
index 751e78044d..34a334b3e7 100644
--- a/sources/scalac/ast/TreeGen.java
+++ b/sources/scalac/ast/TreeGen.java
@@ -487,6 +487,7 @@ public class TreeGen implements Kinds, Modifiers, TypeTags {
Global.instance.nextPhase();
Type symtype = qual.type.memberType(sym);
Global.instance.prevPhase();
+ sym.flags |= ACCESSED | SELECTOR;
return make.Select(pos, sym, qual).setType(deref(symtype));
}
@@ -506,6 +507,7 @@ public class TreeGen implements Kinds, Modifiers, TypeTags {
Global.instance.nextPhase();
Type symtype = sym.type();
Global.instance.prevPhase();
+ sym.flags |= ACCESSED;
return make.Ident(pos, sym).setType(deref(symtype));
}
diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java
index ac4d38e261..7a33403004 100644
--- a/sources/scalac/symtab/Definitions.java
+++ b/sources/scalac/symtab/Definitions.java
@@ -361,13 +361,13 @@ public class Definitions {
EQUALS = new TermSymbol(
Position.NOPOS, Names.equals, ANY_CLASS, 0);
- EQUALS.setInfo(Type.MethodType(new Symbol[]{newParameter(EQUALS, JAVA_OBJECT_TYPE)},
+ EQUALS.setInfo(Type.MethodType(new Symbol[]{newParameter(EQUALS, ANY_TYPE)},
BOOLEAN_TYPE));
ANY_CLASS.members().enter(EQUALS);
EQ = new TermSymbol(
Position.NOPOS, Names.eq, ANY_CLASS, 0);
- EQ.setInfo(Type.MethodType(new Symbol[]{newParameter(EQ, JAVA_OBJECT_TYPE)},
+ EQ.setInfo(Type.MethodType(new Symbol[]{newParameter(EQ, ANY_TYPE)},
BOOLEAN_TYPE));
ANY_CLASS.members().enter(EQ);
diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java
index e53bbd92d4..242e6c64ce 100644
--- a/sources/scalac/symtab/Modifiers.java
+++ b/sources/scalac/symtab/Modifiers.java
@@ -62,7 +62,6 @@ 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 OVERLOADFLAGS = DEFERRED | OVERRIDE | FINAL;
public static class Helper {
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index ca36dfb663..e36dc1489e 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -977,13 +977,8 @@ public abstract class Symbol implements Modifiers, Kinds {
assert isTerm() : Debug.show(this);
assert this.name == that.name : Debug.show(this) + " <> " + Debug.show(that);
assert this.owner == that.owner : Debug.show(this) + " != " + Debug.show(that);
- assert (this.flags & that.flags & JAVA) != 0 ||
- (this.flags & OVERLOADFLAGS) == (that.flags & OVERLOADFLAGS)
- : Integer.toHexString(this.flags) + "@" + Debug.show(this) + " <> " + Integer.toHexString(that.flags) + "@" + Debug.show(that);
assert this.isConstructor() == that.isConstructor();
- int overflags =
- ((this.flags | that.flags) & (JAVA | OVERLOADFLAGS)) |
- (this.flags & that.flags & ACCESSFLAGS);
+ int overflags = this.flags & that.flags & (JAVA | ACCESSFLAGS);
TermSymbol overloaded = (this.isConstructor())
? TermSymbol.newConstructor(this.constructorClass(), overflags)
: new TermSymbol(pos, name, owner, overflags);
@@ -1062,8 +1057,8 @@ public abstract class Symbol implements Modifiers, Kinds {
}
}
- /** The symbol which is overridden by this symbol in base class `base'
- * `base' must be a superclass of this.owner().
+ /** The symbol which overrides this symbol in subclass `sub'
+ * `sub' must be a subclass of this.owner().
*/
public Symbol overridingSymbol(Type sub) {
assert !isOverloaded() : this;
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index 339c09b38a..21fdf32917 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -1447,7 +1447,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
for (int i = 0; i < ps.length; i++) {
Symbol p1 = ps1[i];
Symbol p = ps[i];
- if (!p1.type().isSubType(p.type()) ||
+ if (!p1.type().isSameAs(p.type()) ||
(p1.flags & (Modifiers.DEF | Modifiers.REPEATED)) !=
(p.flags & (Modifiers.DEF | Modifiers.REPEATED)))
return false;
@@ -1461,8 +1461,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
case PolyType(Symbol[] ps, Type res):
if (ps.length != ps1.length) return false;
for (int i = 0; i < ps.length; i++)
- if (!ps1[i].info().subst(ps1, ps).isSubType(ps[i].info()) ||
- !ps[i].loBound().isSubType(ps1[i].loBound().subst(ps1, ps)))
+ if (!ps1[i].info().subst(ps1, ps).isSameAs(ps[i].info()) ||
+ !ps[i].loBound().isSameAs(ps1[i].loBound().subst(ps1, ps)))
return false;
return res.isSubType(res1.subst(ps1, ps));
}
diff --git a/sources/scalac/symtab/classfile/JavaTypeCreator.java b/sources/scalac/symtab/classfile/JavaTypeCreator.java
index 9ef282ba56..395778adec 100644
--- a/sources/scalac/symtab/classfile/JavaTypeCreator.java
+++ b/sources/scalac/symtab/classfile/JavaTypeCreator.java
@@ -72,10 +72,16 @@ public class JavaTypeCreator implements JavaTypeFactory {
for (int i = 0; i < args.length; i++) {
args[i] = new TermSymbol(
Position.NOPOS, Name.fromString("x" + i), Symbol.NONE, Modifiers.PARAM);
- args[i].setInfo(argtpes[i]);
+ args[i].setInfo(objToAny(argtpes[i]));
}
return new MethodType(args, restpe);
}
+ private Type objToAny(Type tp) {
+ if (tp.isSameAs(global.definitions.JAVA_OBJECT_TYPE))
+ return global.definitions.ANY_TYPE;
+ else
+ return tp;
+ }
public Type packageType(Name packagename) {
return null;
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index 6d54de146c..55b6324880 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -212,20 +212,44 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
/** Check that `sym' is accessible as a member of tree `site' in current context.
*/
- void checkAccessible(int pos, Symbol sym, Tree site) {
- if (!isAccessible(sym, site)) {
- error(pos, sym + " cannot be accessed in " + site.type);
- }
- if (site instanceof Tree.Super && (sym.flags & DEFERRED) != 0) {
- Symbol sym1 = context.enclClass.owner.thisSym().info().lookup(sym.name);
- if ((sym1.flags & OVERRIDE) == 0 || (sym1.flags & DEFERRED) != 0)
- error(pos, "symbol accessed from super may not be abstract");
+ Type checkAccessible(int pos, Symbol sym, Type symtype, Tree site) {
+ switch (symtype) {
+ case OverloadedType(Symbol[] alts, Type[] alttypes):
+ int nacc = 0;
+ for (int i = 0; i < alts.length; i++) {
+ if (isAccessible(alts[i], site)) {
+ nacc++;
+ }
+ }
+ if (nacc == 0) {
+ error(pos, sym + " cannot be accessed in " + site.type.widen());
+ return Type.ErrorType;
+ } else {
+ Symbol[] alts1 = new Symbol[nacc];
+ Type[] alttypes1 = new Type[nacc];
+ nacc = 0;
+ for (int i = 0; i < alts.length; i++) {
+ if (isAccessible(alts[i], site)) {
+ alts1[nacc] = alts[i];
+ alttypes1[nacc] = alttypes[i];
+ nacc++;
+ }
+ }
+ return Type.OverloadedType(alts1, alttypes1);
+ }
+ default:
+ if (isAccessible(sym, site)) {
+ return symtype;
+ } else {
+ error(pos, sym + " cannot be accessed in " + site.type.widen());
+ return Type.ErrorType;
+ }
}
}
/** Is `sym' accessible as a member of tree `site' in current context?
*/
- boolean isAccessible(Symbol sym, Tree site) {
+ private boolean isAccessible(Symbol sym, Tree site) {
return
(sym.flags & (PRIVATE | PROTECTED)) == 0
||
@@ -783,8 +807,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Symbol owner = sym.owner();
if (sym.kind == VAL && (sym.flags & (PRIVATE | SEALED)) == 0 &&
owner != null && owner.kind == CLASS &&
- (owner.flags & FINAL) != 0)
+ (owner.flags & FINAL) != 0) {
+ System.out.println(sym + " is final");
sym.flags |= FINAL;
+ }
sym = enterInScope(sym);
}
tree.setSymbol(sym);
@@ -835,6 +861,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
context.scope.enter(sym);
} else if (sym.kind == VAL && other.kind == VAL) {
// it's an overloaded definition
+ /*
if (((sym.flags ^ other.flags) & SOURCEFLAGS) != 0) {
// todo: refine, DEFERRED, MUTABLE and OVERRIDE should be
// treated specially; maybe only PRIVATE and PROTECTED?
@@ -843,9 +870,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
": modifier lists differ in " +
Modifiers.Helper.toString(
(sym.flags ^ other.flags) & SOURCEFLAGS));
- } else {
- e.setSymbol(other.overloadWith(sym));
- }
+ */
+ e.setSymbol(other.overloadWith(sym));
} else {
error(sym.pos,
sym.nameString() + " is already defined as " +
@@ -1247,11 +1273,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (tree.type.isObjectType()) {
// insert apply method
Symbol applyMeth = tree.type.lookup(Names.apply);
- if (applyMeth != Symbol.NONE && isAccessible(applyMeth, tree)) {
- applyMeth.flags |= (ACCESSED | SELECTOR);
+ if (applyMeth != Symbol.NONE) {
+ Type applyType = checkAccessible(
+ tree.pos, applyMeth, tree.type.memberType(applyMeth),
+ tree);
tree = make.Select(tree.pos, tree, Names.apply)
.setSymbol(applyMeth)
- .setType(tree.type.memberType(applyMeth));
+ .setType(applyType);
return adapt(tree, mode, pt);
}
}
@@ -1362,14 +1390,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
//System.out.println(name);//DEBUG
return error(tree.pos, "not found: " + decode(name));
} else {
- sym.flags |= ACCESSED;
if (sym.owner().kind == CLASS) {
pre = nextcontext.enclClass.owner.thisType();
if (!sym.owner().isPackage()) {
Tree qual1 = makeStableId(tree.pos, pre);
tree = make.Select(tree.pos, qual1, name);
- if (context.enclClass != nextcontext.enclClass)
- sym.flags |= SELECTOR;
//System.out.println(name + " :::> " + tree + " " + qual1.symbol());//DEBUG
}
} else {
@@ -1395,15 +1420,15 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
nextimports = nextimports.prev;
}
sym = sym1;
- sym.flags |= (ACCESSED | SELECTOR);
qual = lastimports.importPrefix().duplicate();
pre = qual.type;
//new TextTreePrinter().print(name + " => ").print(lastimports.tree).print("." + name).println().end();//DEBUG
tree = make.Select(tree.pos, qual, name);
}
- if (qual != Tree.Empty) checkAccessible(tree.pos, sym, qual);
Type symtype = (sym.isType() ? sym.typeConstructor() : sym.type())
.asSeenFrom(pre, sym.owner());
+ if (qual != Tree.Empty)
+ symtype = checkAccessible(tree.pos, sym, symtype, qual);
if (symtype == Type.NoType)
return error(tree.pos, "not found: " + decode(name));
if ((pt != null && pt.isStable() || (mode & QUALmode) != 0) && sym.isStable()) {
@@ -1430,14 +1455,12 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
return error(tree.pos,
decode(name) + " is not a member of " + qual.type.widen());
} else {
- checkAccessible(tree.pos, sym, qual);
- sym.flags |= ACCESSED;
- if (!TreeInfo.isSelf(qual, context.enclClass.owner))
- sym.flags |= SELECTOR;
Type symtype = (sym.isType() ? sym.typeConstructor() : sym.type())
.asSeenFrom(qual.type, sym.owner());
if (symtype == Type.NoType)
return error(tree.pos, "not found: " + decode(name));
+ else
+ symtype = checkAccessible(tree.pos, sym, symtype, qual);
//System.out.println(sym.name + ":" + symtype);//DEBUG
if (uninst.length != 0) {
switch (symtype) {
@@ -2144,8 +2167,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Symbol tsym = TreeInfo.methSymbol(fn1);
if (tsym.kind != ERROR) {
assert tsym.isType() : tsym;
- Type tp = fn1.type.unalias();
- switch (tp) {
+ switch (fn1.type.unalias()) {
case TypeRef(Type pre, Symbol c, Type[] argtypes):
if (c.kind == CLASS) {
c.initialize();
@@ -2154,7 +2176,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
fn1 = gen.mkRef(fn1.pos, pre, constr);
switch (fn1) {
case Select(Tree fn1qual, _):
- checkAccessible(fn1.pos, constr, fn1qual);
+ fn1.type = checkAccessible(
+ fn1.pos, constr, fn1.type, fn1qual);
}
if (tsym == c) {
switch (fn0) {
diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java
index d25c547e20..24c452cf70 100644
--- a/sources/scalac/typechecker/RefCheck.java
+++ b/sources/scalac/typechecker/RefCheck.java
@@ -43,6 +43,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
private Unit unit;
private Definitions defs = global.definitions;
private Infer infer = new Infer(this);
+ private Symbol enclClass;
public void apply(Unit unit) {
this.unit = unit;
@@ -65,13 +66,17 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
Type[] closure = clazz.closure();
HashMap/*<Symbol,Symbol>*/ overrides = null;
for (int i = 0; i < closure.length; i++) {
- for (Scope.SymbolIterator it = closure[i].members().iterator();
+ for (Scope.SymbolIterator it = closure[i].members().iterator(true);
it.hasNext();) {
Symbol other = it.next();
- Symbol member = ((other.flags & PRIVATE) != 0) ? other
+ Symbol members = ((other.flags & PRIVATE) != 0) ? other
: clazz.info().lookup(other.name);
- if (member != other && member.kind != NONE)
- checkOverride(pos, clazz, member, other);
+ Symbol member = Symbol.NONE;
+ if (members.kind != NONE &&
+ members.owner() != other.owner() &&
+ (members.owner() == clazz ||
+ !members.owner().isSubClass(other.owner())))
+ member = checkOverride(pos, clazz, members, other);
if (clazz.kind == CLASS && (clazz.flags & ABSTRACTCLASS) == 0) {
if ((member.flags & DEFERRED) != 0) {
abstractClassError(
@@ -97,7 +102,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
if ((other.flags & DEFERRED) != 0) {
abstractClassError(
clazz, member + member.locationString() +
- " is marked `override' and overrides only abstract members");
+ " is marked `override' and overrides only abstract members" + other + other.locationString());
}
}
}
@@ -125,10 +130,33 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
* 7. If O and M are values, then M's type is a subtype of O's type.
* 8. If O is an immutable value, then so is M.
*/
- void checkOverride(int pos, Symbol clazz, Symbol member, Symbol other) {
+ Symbol checkOverride(int pos, Symbol clazz, Symbol members, Symbol other) {
+ Type self = clazz.thisType();
+ Symbol member = members;
+ Type memberinfo = normalizedInfo(self, member);
+ Type otherinfo = normalizedInfo(self, other);
+ switch (memberinfo) {
+ case OverloadedType(Symbol[] alts, Type[] alttypes):
+ for (int i = 0; i < alts.length; i++) {
+ if (alttypes[i].isSubType(otherinfo)) {
+ if (member == members) {
+ member = alts[i];
+ memberinfo = alttypes[i];
+ } else {
+ unit.error(
+ pos,
+ "ambiguous override: both " +
+ member + ":" + memberinfo +
+ "\n and " + alts[i] + ":" + alttypes[i] +
+ "\n override " + other + ":" + otherinfo +
+ other.locationString());
+ }
+ }
+ }
+ if (member == members) {
+ }
+ }
if (member.owner() == clazz) pos = member.pos;
- else if (member.owner().isSubClass(other.owner()))
- return; // everything was already checked elsewhere
if ((member.flags & PRIVATE) != 0) {
overrideError(pos, member, other, "has weaker access privileges; it should not be private");
@@ -149,7 +177,6 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
":\n both are inherited from mixin classes; " +
"\n an overriding definition in the current template is required");
} else {
- Type self = clazz.thisType();
switch (other.kind) {
case CLASS:
overrideError(pos, member, other, "cannot override a class");
@@ -162,9 +189,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
if (other.isConstructor())
overrideError(pos, member, other,
"cannot override a class constructor");
- Type selftype = normalizedInfo(self, member);
- Type othertype = normalizedInfo(self, other);
- if (!selftype.isSubType(othertype))
+ if (!memberinfo.isSubType(otherinfo))
overrideTypeError(pos, member, other, self, false);
if (member.kind == TYPE &&
!self.memberLoBound(other).isSubType(
@@ -173,6 +198,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
}
}
+ return member;
}
void overrideError(int pos, Symbol member, Symbol other, String msg) {
@@ -842,10 +868,14 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
Symbol sym = tree.symbol();
switch (tree) {
case ClassDef(_, _, Tree.AbsTypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ):
+ Symbol enclClassPrev = enclClass;
+ enclClass = sym;
validateVariance(sym, sym.info(), CoVariance);
validateVariance(sym, sym.typeOfThis(), CoVariance);
- return super.transform(
+ Tree tree1 = super.transform(
copy.ClassDef(tree, tree.symbol(), tparams, vparams, tpe, addCaseMethods(templ, tree.symbol())));
+ enclClass = enclClassPrev;
+ return tree1;
case DefDef(_, _, _, _, _, _):
validateVariance(sym, sym.type(), CoVariance);
@@ -933,10 +963,23 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
maxindex[i] = symindex;
}
}
+ sym.flags |= ACCESSED;
return elimTypeNode(tree);
+
+ case Select(Tree qual, Name name):
+ sym.flags |= ACCESSED;
+ if (!TreeInfo.isSelf(qual, enclClass))
+ sym.flags |= SELECTOR;
+ if (qual instanceof Tree.Super && (sym.flags & DEFERRED) != 0) {
+ Symbol sym1 = enclClass.thisSym().info().lookup(sym.name);
+ if ((sym1.flags & OVERRIDE) == 0 || (sym1.flags & DEFERRED) != 0)
+ unit.error(tree.pos,
+ "symbol accessed from super may not be abstract");
+ }
+ return elimTypeNode(super.transform(tree));
+
default:
return elimTypeNode(super.transform(tree));
}
-
}
}
diff --git a/test/files/neg/bug25.check b/test/files/neg/bug25.check
index 75ae98eac7..c620e8498f 100644
--- a/test/files/neg/bug25.check
+++ b/test/files/neg/bug25.check
@@ -1,4 +1,4 @@
-bug25.scala:5: constructor javax.rmi.PortableRemoteObject cannot be accessed in javax.rmi.type
+bug25.scala:5: constructor javax.rmi.PortableRemoteObject cannot be accessed in javax.rmi
class A extends javax.rmi.PortableRemoteObject();
^
one error found
diff --git a/test/neg/bug25.check b/test/neg/bug25.check
index 75ae98eac7..c620e8498f 100644
--- a/test/neg/bug25.check
+++ b/test/neg/bug25.check
@@ -1,4 +1,4 @@
-bug25.scala:5: constructor javax.rmi.PortableRemoteObject cannot be accessed in javax.rmi.type
+bug25.scala:5: constructor javax.rmi.PortableRemoteObject cannot be accessed in javax.rmi
class A extends javax.rmi.PortableRemoteObject();
^
one error found