summaryrefslogtreecommitdiff
path: root/sources/scalac/typechecker
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-09-15 20:20:14 +0000
committerMartin Odersky <odersky@gmail.com>2003-09-15 20:20:14 +0000
commitdc6ec50a08dcd17aa65a73701abd6963b78a00bc (patch)
tree00e884ffbe6776f51be59bb249012190ab757a08 /sources/scalac/typechecker
parent1b77651f90d9b4132e419409295f0d3c6153cf41 (diff)
downloadscala-dc6ec50a08dcd17aa65a73701abd6963b78a00bc.tar.gz
scala-dc6ec50a08dcd17aa65a73701abd6963b78a00bc.tar.bz2
scala-dc6ec50a08dcd17aa65a73701abd6963b78a00bc.zip
*** empty log message ***
Diffstat (limited to 'sources/scalac/typechecker')
-rw-r--r--sources/scalac/typechecker/Analyzer.java14
-rw-r--r--sources/scalac/typechecker/Infer.java18
-rw-r--r--sources/scalac/typechecker/RefCheck.java55
3 files changed, 58 insertions, 29 deletions
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index 063108a9d0..05657ba759 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -319,20 +319,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
sym.flags &= ~DEFERRED;
}
}
- if ((sym.flags & OVERRIDE) != 0) {
- int i = -1;
- if (sym.owner().kind == CLASS) {
- Type[] parents = sym.owner().info().parents();
- i = parents.length - 1;
- while (i >= 0 &&
- parents[i].lookupNonPrivate(sym.name).kind == NONE)
- i--;
- }
- if (i < 0) {
- error(sym.pos, sym + " overrides nothing");
- sym.flags &= ~OVERRIDE;
- }
- }
checkNoConflict(sym, DEFERRED, PRIVATE);
checkNoConflict(sym, FINAL, SEALED);
checkNoConflict(sym, FINAL, PRIVATE);
diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java
index 5dcf9bf0db..05d8916d66 100644
--- a/sources/scalac/typechecker/Infer.java
+++ b/sources/scalac/typechecker/Infer.java
@@ -123,6 +123,24 @@ public class Infer implements Modifiers, Kinds {
}
}
return tree;
+
+ case TypeApply(Tree fun, Tree[] targs):
+ boolean proceed = true;
+ switch (fun.type) {
+ case PolyType(Symbol[] tparams1, _):
+ if (tparams1.length == tparams.length &&
+ tparams1[0] == tparams[0] &&
+ targs.length == tparams.length) {
+ proceed = false;
+ for (int i = 0; i < tparams.length; i++)
+ if (!typeSubstituter.matches(targs[i].type.symbol(), tparams[i]))
+ proceed = true;
+ }
+ }
+ Tree fun1 = proceed ? transform(fun) : fun;
+ Tree[] targs1 = transform(targs);
+ return copy.TypeApply(tree, fun1, targs1);
+
/*
case TypeTerm():
Symbol sym = tree.type.symbol();
diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java
index da3bef4476..9c493db761 100644
--- a/sources/scalac/typechecker/RefCheck.java
+++ b/sources/scalac/typechecker/RefCheck.java
@@ -71,6 +71,22 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
checkOverride(pos, clazz, it.next(), overrides);
}
}
+
+ Type[] parents = clazz.info().parents();
+ for (Scope.SymbolIterator it = clazz.members().iterator(true);
+ it.hasNext();) {
+ Symbol sym = it.next();
+ if ((sym.flags & OVERRIDE) != 0) {
+ int i = parents.length - 1;
+ while (i >= 0 && sym.overriddenSymbol(parents[i]).kind == NONE)
+ i--;
+ if (i < 0) {
+ unit.error(sym.pos, sym + " overrides nothing");
+ sym.flags &= ~OVERRIDE;
+ }
+ }
+ }
+
for (Iterator/*<Symbol>*/ it = overrides.keySet().iterator();
it.hasNext();) {
Symbol member = (Symbol) it.next();
@@ -89,12 +105,13 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
if ((other.flags & PRIVATE) == 0) {
Symbol member1 = clazz.info().lookup(other.name);
if (member1.kind != NONE && member1.owner() != other.owner()) {
+ Type self = clazz.thisType();
+ Type otherinfo = normalizedInfo(self, other);
+ Type template = resultToAny(otherinfo);
switch (member1.info()) {
case OverloadedType(Symbol[] alts, _):
- Type self = clazz.thisType();
- Type otherinfo = normalizedInfo(self, other);
for (int i = 0; i < alts.length; i++) {
- if (normalizedInfo(self, alts[i]).isSubType(otherinfo)) {
+ if (normalizedInfo(self, alts[i]).isSubType(template)) {
if (member == other)
member = alts[i];
else
@@ -109,12 +126,14 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
}
break;
default:
- member = member1;
+ if (normalizedInfo(self, member1).isSubType(template)) {
+ member = member1;
+ }
}
}
- }
- if (member != other) {
- checkOverride(pos, clazz, member, other);
+ if (member != other) {
+ checkOverride(pos, clazz, member, other);
+ }
}
if (clazz.kind == CLASS && (clazz.flags & ABSTRACTCLASS) == 0) {
if ((member.flags & DEFERRED) != 0) {
@@ -123,13 +142,24 @@ 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.flags & OVERRIDE) != 0 &&
+ } else if (member != other &&
+ (member.flags & OVERRIDE) != 0 &&
((other.flags & DEFERRED) == 0 ||
overrides.get(member) == null))
overrides.put(member, other);
}
}
//where
+ private Type resultToAny(Type tp) {
+ switch (tp) {
+ case PolyType(Symbol[] tparams, Type restp):
+ return Type.PolyType(tparams, resultToAny(restp));
+ case MethodType(Symbol[] tparams, Type restp):
+ return Type.MethodType(tparams, Type.AnyType);
+ default:
+ return defs.ANY_TYPE;
+ }
+ }
private void abstractClassError(Symbol clazz, String msg) {
if (clazz.isAnonymousClass())
unit.error(clazz.pos, "object creation impossible, since " + msg);
@@ -227,12 +257,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
}
Type normalizedInfo(Type site, Symbol sym) {
- Type tp = site.memberInfo(sym);
- switch (tp) {
- case PolyType(Symbol[] tparams, Type restp):
- if (tparams.length == 0) return restp;
- }
- return tp;
+ return site.memberInfo(sym).derefDef();
}
String infoString(Symbol sym, Type symtype, boolean lobound) {
@@ -946,7 +971,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
//System.out.println("name: "+name);
Scope.Entry e = scopes[level].lookupEntry(name);
//System.out.println("sym: "+sym);
- if (sym.isLocal() && sym == e.sym) {
+ if (sym != null && sym.isLocal() && sym == e.sym) {
int i = level;
while (scopes[i] != e.owner) i--;
int symindex = ((Integer) symIndex.get(tree.symbol())).intValue();