diff options
author | Martin Odersky <odersky@gmail.com> | 2004-04-06 17:57:30 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2004-04-06 17:57:30 +0000 |
commit | 35f72d0a599e3aca2940e295052c0275c0a32533 (patch) | |
tree | 86c40542dc2a3412b4a0fcb76a71c1e1141522bf /sources/scalac | |
parent | 17c857d22ec405ec89e87e40206aecc2be84255d (diff) | |
download | scala-35f72d0a599e3aca2940e295052c0275c0a32533.tar.gz scala-35f72d0a599e3aca2940e295052c0275c0a32533.tar.bz2 scala-35f72d0a599e3aca2940e295052c0275c0a32533.zip |
*** empty log message ***
Diffstat (limited to 'sources/scalac')
-rw-r--r-- | sources/scalac/ast/TreeGen.java | 2 | ||||
-rw-r--r-- | sources/scalac/symtab/ClosureHistory.java | 2 | ||||
-rw-r--r-- | sources/scalac/symtab/Symbol.java | 31 | ||||
-rw-r--r-- | sources/scalac/symtab/Type.java | 63 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/Pickle.java | 14 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/UnPickle.java | 7 | ||||
-rw-r--r-- | sources/scalac/typechecker/RefCheck.java | 39 |
7 files changed, 132 insertions, 26 deletions
diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java index 1bbb32aebf..4abd940f9c 100644 --- a/sources/scalac/ast/TreeGen.java +++ b/sources/scalac/ast/TreeGen.java @@ -1094,7 +1094,7 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { AbsTypeDef tree = make.AbsTypeDef( sym.pos, sym, - TypeTerm(sym.pos, sym.nextInfo()), + TypeTerm(sym.pos, sym.isViewBounded() ? sym.vuBound() : sym.nextInfo()), TypeTerm(sym.pos, sym.loBound())); tree.setType(Type.NoType); return tree; diff --git a/sources/scalac/symtab/ClosureHistory.java b/sources/scalac/symtab/ClosureHistory.java index 8825fb3e20..c17ad46f90 100644 --- a/sources/scalac/symtab/ClosureHistory.java +++ b/sources/scalac/symtab/ClosureHistory.java @@ -14,6 +14,7 @@ import java.util.TreeMap; import scalac.Global; import scalac.framework.History; import scalac.util.Debug; +import scalac.util.ArrayApply; /** This class implements a closure history. */ public class ClosureHistory extends History { @@ -43,6 +44,7 @@ public class ClosureHistory extends History { closure[0] = clasz.type(); for (int i = 1; i < closure.length; i++) closure[i] = (Type)types.next(); + //System.out.println("closure(" + owner + ") = " + ArrayApply.toString(closure));//DEBUG return closure; } diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index c65bdcdc6c..ccd9f2632a 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -504,6 +504,12 @@ public abstract class Symbol implements Modifiers, Kinds { throw new ApplicationError("setLoBound inapplicable for " + this); } + /** Set the view bound of this type variable + */ + public Symbol setVuBound(Type lobound) { + throw new ApplicationError("setVuBound inapplicable for " + this); + } + /** Add an auxiliary constructor to class. */ public void addConstructor(Symbol constr) { @@ -575,6 +581,13 @@ public abstract class Symbol implements Modifiers, Kinds { return kind == VAL && (flags & MUTABLE) != 0; } + /** Does this symbol denote a view bounded type variable? */ + public final boolean isViewBounded() { + Global global = Global.instance; + return kind == TYPE && (flags & VIEWBOUND) != 0 && + global.currentPhase.id <= global.PHASE.REFCHECK.id(); + } + /** * Does this symbol denote a final method? A final method is one * that can't be overridden in a subclass. This method assumes @@ -1278,6 +1291,12 @@ public abstract class Symbol implements Modifiers, Kinds { return Global.instance.definitions.ALL_TYPE(); } + /** The view bound of this type variable + */ + public Type vuBound() { + return Global.instance.definitions.ANY_TYPE(); + } + /** Get this.type corresponding to this symbol */ public Type thisType() { @@ -1757,6 +1776,7 @@ final class AliasTypeSymbol extends TypeSymbol { final class AbsTypeSymbol extends TypeSymbol { private Type lobound = null; + private Type vubound = null; /** Initializes this instance. */ AbsTypeSymbol(int pos, Name name, Symbol owner, int flags, int attrs) { @@ -1769,14 +1789,25 @@ final class AbsTypeSymbol extends TypeSymbol { return lobound == null ? Global.instance.definitions.ALL_TYPE() : lobound; } + public Type vuBound() { + initialize(); + return vubound == null ? Global.instance.definitions.ANY_TYPE() : vubound; + } + public Symbol setLoBound(Type lobound) { this.lobound = lobound; return this; } + public Symbol setVuBound(Type vubound) { + this.vubound = vubound; + return this; + } + protected TypeSymbol cloneTypeSymbolImpl(Symbol owner, int attrs) { TypeSymbol clone = new AbsTypeSymbol(pos, name, owner, flags, attrs); clone.setLoBound(loBound()); + clone.setVuBound(vuBound()); return clone; } diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 9adcade4a2..4bff125e53 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -1035,8 +1035,10 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } for (int i = 0; i < syms2.length; i++) { syms2[i].setInfo(syms1[i].info().subst(syms1, syms2)); - if (syms2[i].kind == TYPE) + if (syms2[i].kind == TYPE) { syms2[i].setLoBound(syms1[i].loBound().subst(syms1, syms2)); + syms2[i].setVuBound(syms1[i].vuBound().subst(syms1, syms2)); + } } for (int i = 0; i < syms2.length; i++) { members2.enter(syms2[i]); @@ -1086,6 +1088,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { if (!dontClone) sym = sym.cloneSymbol(); sym.setLoBound(lb1); } + Type vb = sym.vuBound(); + Type vb1 = apply(vb); + if (vb != vb1) { + if (!dontClone) sym = sym.cloneSymbol(); + sym.setVuBound(vb1); + } } return sym; } @@ -1319,6 +1327,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return sym.loBound().asSeenFrom(this, sym.owner()); } + /** The view bound of `sym', seen as a member of this type. + */ + public Type memberVuBound(Symbol sym) { + return sym.vuBound().asSeenFrom(this, sym.owner()); + } + // Substitutions --------------------------------------------------------------- /** A common map superclass for symbol/symbol and type/symbol substitutions. @@ -1920,7 +1934,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { if (ps.length != ps1.length) return false; for (int i = 0; i < ps.length; i++) if (!ps1[i].info().subst(ps1, ps).isSameAs(ps[i].info()) || - !ps[i].loBound().isSameAs(ps1[i].loBound().subst(ps1, ps))) + !ps[i].loBound().isSameAs(ps1[i].loBound().subst(ps1, ps)) || + !ps[i].vuBound().isSameAs(ps1[i].vuBound().subst(ps1, ps))) return false; return res.isSubType(res1.subst(ps1, ps)); } @@ -1979,9 +1994,9 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return true; } - case TypeRef(_, Symbol sym, Type[] args): + case TypeRef(_, Symbol sym, _): switch (that) { - case TypeRef(Type pre1, Symbol sym1, _): + case TypeRef(_, Symbol sym1, _): if (sym1.kind == TYPE && this.isSubType(that.loBound())) return true; } @@ -2092,7 +2107,9 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { self.memberInfo(sym).subst(tparams, targs) .isSubType(sym1.info().substThis(sym1.owner(), self)) && sym1.loBound().substThis(sym1.owner(), self) - .isSubType(self.memberLoBound(sym).subst(tparams, targs)) + .isSubType(self.memberLoBound(sym).subst(tparams, targs)) && + self.memberVuBound(sym).subst(tparams, targs) + .isSubType(sym1.vuBound().substThis(sym1.owner(), self)) || (sym.kind == TYPE && sym1.kind == ALIAS && sym1.info().unalias().isSameAs(sym.type()))); @@ -2203,7 +2220,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { if (ps.length != ps1.length) return false; for (int i = 0; i < ps.length; i++) if (!ps1[i].info().subst(ps1, ps).isSameAs(ps[i].info()) || - !ps1[i].loBound().subst(ps1, ps).isSameAs(ps[i].loBound())) + !ps1[i].loBound().subst(ps1, ps).isSameAs(ps[i].loBound()) || + !ps1[i].vuBound().subst(ps1, ps).isSameAs(ps[i].vuBound())) return false; return res.isSameAs(res1.subst(ps1, ps)); } @@ -2293,6 +2311,9 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { sym2.owner(), sym1.owner().thisType())) || !sym1.loBound().isSameAs( sym2.loBound().substThis( + sym2.owner(), sym1.owner().thisType())) || + !sym1.vuBound().isSameAs( + sym2.vuBound().substThis( sym2.owner(), sym1.owner().thisType()))) return false; } @@ -2656,6 +2677,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { private static Type polyLub(Type[] tps, Symbol[] tparams0) { Type[][] hiboundss = new Type[tparams0.length][tps.length]; Type[][] loboundss = new Type[tparams0.length][tps.length]; + Type[][] vuboundss = new Type[tparams0.length][tps.length]; Type[] restps = new Type[tps.length]; for (int i = 0; i < tps.length; i++) { switch (tps[i]) { @@ -2666,6 +2688,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { .subst(tparams, tparams0); loboundss[j][i] = tparams[j].loBound() .subst(tparams, tparams0); + vuboundss[j][i] = tparams[j].vuBound() + .subst(tparams, tparams0); } restps[i] = restp.subst(tparams, tparams0); } else { @@ -2678,15 +2702,18 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } Type[] hibounds = new Type[tparams0.length]; Type[] lobounds = new Type[tparams0.length]; + Type[] vubounds = new Type[tparams0.length]; for (int j = 0; j < tparams0.length; j++) { hibounds[j] = glb(hiboundss[j]); lobounds[j] = lub(loboundss[j]); + vubounds[j] = glb(vuboundss[j]); } Symbol[] tparams = new Symbol[tparams0.length]; for (int j = 0; j < tparams.length; j++) { tparams[j] = tparams0[j].cloneSymbol(Symbol.NONE) .setInfo(hibounds[j].subst(tparams0, tparams)) - .setLoBound(lobounds[j].subst(tparams0, tparams)); + .setLoBound(lobounds[j].subst(tparams0, tparams)) + .setVuBound(vubounds[j].subst(tparams0, tparams)); } return Type.PolyType(tparams, lub(restps).subst(tparams0, tparams)); } @@ -2899,11 +2926,15 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { private static boolean addMember(Scope s, Symbol sym, Type glbThisType) { Type syminfo = sym.info().substThis(sym.owner(), glbThisType); Type symlb = sym.loBound().substThis(sym.owner(), glbThisType); + Type symvb = sym.vuBound().substThis(sym.owner(), glbThisType); Scope.Entry e = s.lookupEntry(sym.name); if (e == Scope.Entry.NONE) { Symbol sym1 = sym.cloneSymbol(glbThisType.symbol()); sym1.setInfo(syminfo); - if (sym1.kind == TYPE) sym1.setLoBound(symlb); + if (sym1.kind == TYPE) { + sym1.setLoBound(symlb); + sym1.setVuBound(symvb); + } s.enter(sym1); } else { Type einfo = e.sym.info(); @@ -2926,6 +2957,14 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } else { e.sym.setLoBound(lub(new Type[]{elb, symlb})); } + Type evb = e.sym.vuBound(); + if (evb.isSameAs(symvb)) { + } else if (evb.isSubType(symvb)) { + } else if (symvb.isSubType(evb)) { + e.sym.setVuBound(symvb); + } else { + e.sym.setVuBound(glb(new Type[]{evb, symvb})); + } } } return true; @@ -2934,6 +2973,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { private static Type polyGlb(Type[] tps, Symbol[] tparams0) { Type[][] hiboundss = new Type[tparams0.length][tps.length]; Type[][] loboundss = new Type[tparams0.length][tps.length]; + Type[][] vuboundss = new Type[tparams0.length][tps.length]; Type[] restps = new Type[tps.length]; for (int i = 0; i < tps.length; i++) { switch (tps[i]) { @@ -2944,6 +2984,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { .subst(tparams, tparams0); loboundss[j][i] = tparams[j].loBound() .subst(tparams, tparams0); + vuboundss[j][i] = tparams[j].vuBound() + .subst(tparams, tparams0); } restps[i] = restp.subst(tparams, tparams0); } else { @@ -2956,15 +2998,18 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } Type[] hibounds = new Type[tparams0.length]; Type[] lobounds = new Type[tparams0.length]; + Type[] vubounds = new Type[tparams0.length]; for (int j = 0; j < tparams0.length; j++) { hibounds[j] = lub(hiboundss[j]); lobounds[j] = glb(loboundss[j]); + vubounds[j] = lub(vuboundss[j]); } Symbol[] tparams = new Symbol[tparams0.length]; for (int j = 0; j < tparams.length; j++) { tparams[j] = tparams0[j].cloneSymbol(Symbol.NONE) .setInfo(hibounds[j].subst(tparams0, tparams)) - .setLoBound(lobounds[j].subst(tparams0, tparams)); + .setLoBound(lobounds[j].subst(tparams0, tparams)) + .setVuBound(vubounds[j].subst(tparams0, tparams)); } return Type.PolyType(tparams, glb(restps).subst(tparams0, tparams)); } diff --git a/sources/scalac/symtab/classfile/Pickle.java b/sources/scalac/symtab/classfile/Pickle.java index fcf3143da7..2c46855821 100644 --- a/sources/scalac/symtab/classfile/Pickle.java +++ b/sources/scalac/symtab/classfile/Pickle.java @@ -118,15 +118,18 @@ public class Pickle implements Kinds, Modifiers, EntryTags { if (isLocal(sym)) { putEntry(sym.name); putSymbol(sym.isConstructor() ? sym.constructorClass() : sym.owner()); - putType(sym.info()); switch (sym.kind) { case TYPE: + if (sym.isViewBounded()) putType(sym.vuBound()); + else putType(sym.info()); putType(sym.loBound()); break; case ALIAS: + putType(sym.info()); putSymbol(sym.allConstructors()); break; case CLASS: + putType(sym.info()); putType(sym.typeOfThis()); putSymbol(sym.allConstructors()); for (Scope.SymbolIterator it = sym.members().iterator(); @@ -134,6 +137,7 @@ public class Pickle implements Kinds, Modifiers, EntryTags { putSymbol(it.next()); break; case VAL: + putType(sym.info()); if (sym.isConstructor() && sym == sym.constructorClass().allConstructors()) putSymbol(sym.constructorClass()); @@ -336,25 +340,31 @@ public class Pickle implements Kinds, Modifiers, EntryTags { writeRef(sym.name); writeRef(sym.isConstructor() ? sym.constructorClass() : sym.owner()); writeNat(sym.flags); - writeRef(sym.info()); switch (sym.kind) { case TYPE: + if (sym.isViewBounded()) writeRef(sym.vuBound()); + else writeRef(sym.info()); writeRef(sym.loBound()); break; case ALIAS: + writeRef(sym.info()); writeRef(sym.allConstructors()); break; case CLASS: + writeRef(sym.info()); writeRef(sym.typeOfThis()); writeRef(sym.allConstructors()); break; case VAL: + writeRef(sym.info()); if (sym.isConstructor() && sym == sym.constructorClass().allConstructors()) writeRef(sym.constructorClass()); else if (sym.isModule()) writeRef(sym.moduleClass()); break; + default: + throw new ApplicationError(); } } else if (sym.kind == NONE) { writeByte(NONEsym); diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java index 74a7027424..ba27cbbf60 100644 --- a/sources/scalac/symtab/classfile/UnPickle.java +++ b/sources/scalac/symtab/classfile/UnPickle.java @@ -244,7 +244,12 @@ public class UnPickle implements Kinds, Modifiers, EntryTags, TypeTags { case TYPEsym: entries[n] = sym = owner.newAbstractType( Position.NOPOS, flags, name); - sym.setInfo(getType(inforef, sym)); + if ((flags & VIEWBOUND) != 0) { + sym.setInfo(global.definitions.ANY_TYPE()); + sym.setVuBound(getType(inforef, sym)); + } else { + sym.setInfo(getType(inforef, sym)); + } sym.setLoBound(readTypeRef(sym)); break; diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java index c7e2572d72..2bb96cbe69 100644 --- a/sources/scalac/typechecker/RefCheck.java +++ b/sources/scalac/typechecker/RefCheck.java @@ -58,6 +58,8 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { // Override checking ------------------------------------------------------------ + static final int HIBOUND = 0, LOBOUND = 1, VUBOUND = 2; + static boolean isIncomplete(Symbol sym) { return sym.isDeferred() || sym.isAbstractOverride() && @@ -255,15 +257,17 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { if (other.typeParams().length != 0) overrideError(pos, member, other, "may not override parameterized type"); if (!self.memberType(member).isSameAs(self.memberType(other))) - overrideTypeError(pos, member, other, self, false); + overrideTypeError(pos, member, other, self, HIBOUND); break; case TYPE: if (member.typeParams().length != 0) overrideError(pos, member, other, "may not be parameterized"); if (!self.memberInfo(member).isSubType(self.memberInfo(other))) - overrideTypeError(pos, member, other, self, false); + overrideTypeError(pos, member, other, self, HIBOUND); if (!self.memberLoBound(other).isSubType(self.memberLoBound(member))) - overrideTypeError(pos, member, other, self, true); + overrideTypeError(pos, member, other, self, LOBOUND); + if (!self.memberVuBound(member).isSubType(self.memberVuBound(other))) + overrideTypeError(pos, member, other, self, VUBOUND); break; default: if (other.isConstructor()) @@ -271,7 +275,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { "cannot override a class constructor"); if (!normalizedInfo(self, member).isSubType( normalizedInfo(self, other))) - overrideTypeError(pos, member, other, self, false); + overrideTypeError(pos, member, other, self, HIBOUND); } } } @@ -284,17 +288,25 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { } void overrideTypeError(int pos, Symbol member, Symbol other, Type site, - boolean lobound) { + int boundkind) { if (!other.type().isError() && !member.type().isError()) { - Type memberInfo = lobound ? site.memberLoBound(member) - : normalizedInfo(site, member); - Type otherInfo = lobound ? site.memberLoBound(other) - : normalizedInfo(site, other); + Type memberInfo; + Type otherInfo; + if (boundkind == LOBOUND) { + memberInfo = site.memberLoBound(member); + otherInfo = site.memberLoBound(other); + } else if (boundkind == VUBOUND) { + memberInfo = site.memberVuBound(member); + otherInfo = site.memberVuBound(other); + } else { + memberInfo = normalizedInfo(site, member); + otherInfo = normalizedInfo(site, other); + } unit.error(pos, member + member.locationString() + - infoString(member, memberInfo, lobound) + + infoString(member, memberInfo, boundkind) + "\n cannot override " + other + other.locationString() + - infoString(other, otherInfo, lobound)); + infoString(other, otherInfo, boundkind)); Type.explainTypes(memberInfo, otherInfo); } } @@ -303,10 +315,10 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { return site.memberInfo(sym).derefDef(); } - String infoString(Symbol sym, Type symtype, boolean lobound) { + String infoString(Symbol sym, Type symtype, int boundkind) { switch (sym.kind) { case ALIAS: return ", which equals " + symtype; - case TYPE: return " bounded" + (lobound ? " from below" : "") + " by " + symtype; + case TYPE: return " bounded" + (boundkind == LOBOUND ? " from below" : "") + " by " + symtype; case VAL: return " of type " + symtype; default: return ""; } @@ -956,6 +968,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { case AbsTypeDef(_, _, _, _): validateVariance(sym, sym.info(), CoVariance); validateVariance(sym, sym.loBound(), ContraVariance); + validateVariance(sym, sym.vuBound(), CoVariance); return super.transform(tree); case AliasTypeDef(_, _, _, _): |