summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2008-05-02 14:55:17 +0000
committerMartin Odersky <odersky@gmail.com>2008-05-02 14:55:17 +0000
commit76c76b28f952584210fd851f95877b84f0b688a2 (patch)
tree20dfff67c5d7d092104fd17c66cb597e1c9327b7 /src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
parent8c35b8f863e5b7104deb7bfdce957d6d428cc25f (diff)
downloadscala-76c76b28f952584210fd851f95877b84f0b688a2.tar.gz
scala-76c76b28f952584210fd851f95877b84f0b688a2.tar.bz2
scala-76c76b28f952584210fd851f95877b84f0b688a2.zip
fixed #828, #789, #828.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/RefChecks.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index de1f3f3119..d22ab4942e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -249,8 +249,20 @@ abstract class RefChecks extends InfoTransform {
else clazz.toString() + " needs to be abstract") + ", since " + msg);
clazz.setFlag(ABSTRACT)
}
+ // Find a concrete Java method that overrides `sym' under the erasure model.
+ // Bridge symbols qualify.
+ // Used as a fall back if no overriding symbol of a Java abstract method can be found
+ def javaErasedOverridingSym(sym: Symbol): Symbol =
+ clazz.tpe.findMember(sym.name, PRIVATE, 0, false).filter(other =>
+ !other.isDeferred &&
+ (other hasFlag JAVA) && {
+ val tp1 = erasure.erasure(clazz.thisType.memberType(sym))
+ val tp2 = erasure.erasure(clazz.thisType.memberType(other))
+ atPhase(currentRun.erasurePhase.next)(tp1 matches tp2)
+ })
for (val member <- clazz.tpe.nonPrivateMembers)
- if (member.isDeferred && !(clazz hasFlag ABSTRACT)) {
+ if (member.isDeferred && !(clazz hasFlag ABSTRACT) &&
+ !((member hasFlag JAVA) && javaErasedOverridingSym(member) != NoSymbol)) {
abstractClassError(
false, infoString(member) + " is not defined" + analyzer.varNotice(member))
} else if ((member hasFlag ABSOVERRIDE) && member.isIncompleteIn(clazz)) {
@@ -263,6 +275,12 @@ abstract class RefChecks extends InfoTransform {
}
// 3. Check that concrete classes do not have deferred definitions
// that are not implemented in a subclass.
+ // Note that this is not the same as (2); In a situation like
+ //
+ // class C { def m: Int = 0}
+ // class D extends C { def m: Int }
+ //
+ // (3) is violated but not (2).
def checkNoAbstractDecls(bc: Symbol) {
for (val decl <- bc.info.decls.elements) {
if (decl.isDeferred) {