summaryrefslogtreecommitdiff
path: root/sources/scalac
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2004-04-06 17:57:30 +0000
committerMartin Odersky <odersky@gmail.com>2004-04-06 17:57:30 +0000
commit35f72d0a599e3aca2940e295052c0275c0a32533 (patch)
tree86c40542dc2a3412b4a0fcb76a71c1e1141522bf /sources/scalac
parent17c857d22ec405ec89e87e40206aecc2be84255d (diff)
downloadscala-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.java2
-rw-r--r--sources/scalac/symtab/ClosureHistory.java2
-rw-r--r--sources/scalac/symtab/Symbol.java31
-rw-r--r--sources/scalac/symtab/Type.java63
-rw-r--r--sources/scalac/symtab/classfile/Pickle.java14
-rw-r--r--sources/scalac/symtab/classfile/UnPickle.java7
-rw-r--r--sources/scalac/typechecker/RefCheck.java39
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(_, _, _, _):