diff options
author | Martin Odersky <odersky@gmail.com> | 2003-09-15 20:20:14 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2003-09-15 20:20:14 +0000 |
commit | dc6ec50a08dcd17aa65a73701abd6963b78a00bc (patch) | |
tree | 00e884ffbe6776f51be59bb249012190ab757a08 /sources/scalac/typechecker | |
parent | 1b77651f90d9b4132e419409295f0d3c6153cf41 (diff) | |
download | scala-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.java | 14 | ||||
-rw-r--r-- | sources/scalac/typechecker/Infer.java | 18 | ||||
-rw-r--r-- | sources/scalac/typechecker/RefCheck.java | 55 |
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(); |