summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
Diffstat (limited to 'sources')
-rw-r--r--sources/meta/scalac/checkers/MetaCheckTreeNodes.java4
-rw-r--r--sources/scalac/symtab/Type.java48
-rw-r--r--sources/scalac/typechecker/Analyzer.java25
-rw-r--r--sources/scalac/typechecker/RefCheck.java123
4 files changed, 98 insertions, 102 deletions
diff --git a/sources/meta/scalac/checkers/MetaCheckTreeNodes.java b/sources/meta/scalac/checkers/MetaCheckTreeNodes.java
index d18d012d20..11ad75d77a 100644
--- a/sources/meta/scalac/checkers/MetaCheckTreeNodes.java
+++ b/sources/meta/scalac/checkers/MetaCheckTreeNodes.java
@@ -78,8 +78,8 @@ public class MetaCheckTreeNodes extends AbstractTreeCaseExpander {
case TreeType.Name(TreeKind kind):
if (kind != TreeKind.Any && kind != TreeKind.Test) {
- writer.println("assert " + (kind == TreeKind.Type ? "" : "!")+
- name +".isTypeName() :").indent();
+ writer.println("assert " + name + ".is" + kind + "Name() :")
+ .indent();
printWrongKind(node, name, kind);
writer.println(";").undent();
}
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index e3526f8830..03bee60328 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -1727,36 +1727,23 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
return result;
}
- public boolean specializes0(Symbol sym1) {
- Symbol sym = lookup(sym1.name);
- switch (sym.info()) {
- case NoType:
- return false;
- case OverloadedType(Symbol[] alts, Type[] alttypes):
- for (int i = 0; i < alts.length; i++) {
- if (specializes0(alts[i], sym1)) return true;
- }
- return false;
- default:
- return specializes0(sym, sym1);
- }
- }
-
- private boolean specializes0(Symbol sym, Symbol sym1) {
+ private boolean specializes0(Symbol sym1) {
Type self = narrow();
Symbol[] tparams = symbol().typeParams();
Type[] targs = typeArgs();
+ Symbol sym = lookup(sym1.name);
return
- sym == sym1
- ||
- (sym.kind == sym1.kind || sym1.kind == TYPE) &&
- 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))
- ||
- (sym.kind == TYPE && sym1.kind == ALIAS &&
- sym1.info().unalias().isSameAs(sym.type()));
+ sym.kind != NONE &&
+ (sym == sym1
+ ||
+ (sym.kind == sym1.kind || sym1.kind == TYPE) &&
+ 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))
+ ||
+ (sym.kind == TYPE && sym1.kind == ALIAS &&
+ sym1.info().unalias().isSameAs(sym.type())));
}
/** Is this type the same as that type?
@@ -2163,7 +2150,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
if (tps[i] == ErrorType) {
return new Type[]{ErrorType};
} else {
- assert tps[i].isObjectType() : tps[i];
+ assert tps[i].isObjectType(): tps[i];
for (int j = 0; j < i && !redundant[i]; j++) {
if (!redundant[j]) {
if (tps[i].isSubType(tps[j])) {
@@ -2197,6 +2184,9 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
if (tps.length == 0) return Global.instance.definitions.ALL_TYPE;
+ //If all types are method types with same parameters,
+ //compute lub of their result types.
+
// remove types that are subtypes of some other type.
tps = elimRedundant(tps, true);
if (tps.length == 1) return tps[0];
@@ -2231,8 +2221,6 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
while (j < tps.length) {
rsyms[j] = tps[j].lookupNonPrivate(name);
if (rsyms[j] == sym) break;
- if (rsyms[j].isMethod()) break; // since methods cannot
- // appear in refinements.
rtps[j] = memberTp(tps[j], rsyms[j])
.substThis(tps[j].symbol(), lubThisType);
rlbs[j] = tps[j].memberLoBound(rsyms[j])
@@ -2311,7 +2299,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
if (!members.isEmpty())
comptl = new Type.List(tps[i], comptl);
for (int j = 0; j < parents.length; j++)
- treftl = new Type.List(parents[i], treftl);
+ treftl = new Type.List(parents[j], treftl);
break;
case ThisType(_):
case SingleType(_, _):
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index fc53218f5e..99629712a9 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -1117,7 +1117,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
} catch (Type.Error ex) {
reportTypeError(tree.pos, ex);
tree.type = Type.ErrorType;
- if (tree.hasSymbol() && tree.symbol() == null) tree.setSymbol(Symbol.ERROR);
+ if (tree.hasSymbol()) {
+ if (tree.symbol() != null) tree.symbol().setInfo(Type.ErrorType);
+ else tree.setSymbol(Symbol.ERROR);
+ }
}
this.unit = savedUnit;
@@ -1235,7 +1238,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (clazz.isCaseClass()) {
// set type to instantiated case class constructor
- tree.type = clazz.primaryConstructor().type();
+ tree.type = tree.type.prefix().memberType(
+ clazz.primaryConstructor());
switch (tree.type) {
case PolyType(Symbol[] tparams, Type restp):
try {
@@ -2031,7 +2035,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
return error(tree.pos, "method with return needs result type");
} else {
Symbol enclFun = context.owner.enclMethod();
- if (enclFun.kind == VAL) {
+ if (enclFun.kind == VAL && !enclFun.isConstructor()) {
Tree expr1 = transform(
expr, EXPRmode, enclFun.type().resultType());
return copy.Return(tree, expr1)
@@ -2178,7 +2182,12 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
assert tsym.isType() : tsym;
switch (fn1.type.unalias()) {
case TypeRef(Type pre, Symbol c, Type[] argtypes):
- if (c.kind == CLASS) {
+ if (c.kind != CLASS) {
+ error(tree.pos,
+ tsym + " is not a class; cannot be instantiated");
+ } else if (!pre.isStable()) {
+ error(tree.pos, pre + " is not a legal prefix for a constructor");
+ } else {
c.initialize();
Symbol constr = c.allConstructors();
Tree fn0 = fn1;
@@ -2206,9 +2215,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
//System.out.println(TreeInfo.methSymbol(fn1) + ":" + tp + " --> " + fn1.type + " of " + fn1);//DEBUG
selfcc = TreeInfo.isSelfConstrCall(fn0);
- } else {
- error(tree.pos,
- tsym + " is not a class; cannot be instantiated");
}
break;
default:
@@ -2475,7 +2481,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
} catch (Type.Error ex) {
reportTypeError(tree.pos, ex);
tree.type = Type.ErrorType;
- if (tree.hasSymbol() && tree.symbol() == null) tree.setSymbol(Symbol.ERROR);
+ if (tree.hasSymbol()) {
+ if (tree.symbol() != null) tree.symbol().setInfo(Type.ErrorType);
+ else tree.setSymbol(Symbol.ERROR);
+ }
return tree;
}
}
diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java
index d3a603642a..b2e394458a 100644
--- a/sources/scalac/typechecker/RefCheck.java
+++ b/sources/scalac/typechecker/RefCheck.java
@@ -58,54 +58,76 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
// Override checking ------------------------------------------------------------
/** 1. Check all members of class `clazz' for overriding conditions.
- * 2. Check that only abstract classes have deferred members
+ * 2. Check that only abstract classes have deferred members*
* 3. Check that every member with an `override' modifier
* overrides a concrete member.
*/
void checkAllOverrides(int pos, Symbol clazz) {
Type[] closure = clazz.closure();
- HashMap/*<Symbol,Symbol>*/ overrides = null;
+ HashMap/*<Symbol,Symbol>*/ overrides = new HashMap();
for (int i = 0; i < closure.length; i++) {
for (Scope.SymbolIterator it = closure[i].members().iterator(true);
it.hasNext();) {
- Symbol other = it.next();
- Symbol member = ((other.flags & PRIVATE) != 0) ? other
- : clazz.info().lookup(other.name);
- if (member.owner() == other.owner())
- member = other;
- else if (member.type() instanceof Type.OverloadedType)
- member = findOverriding(pos, clazz, member, other);
- if (member.kind != NONE && member != other)
- checkOverride(pos, clazz, member, other);
- if (clazz.kind == CLASS && (clazz.flags & ABSTRACTCLASS) == 0) {
- if ((member.flags & DEFERRED) != 0) {
- abstractClassError(
- clazz,
- 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) {
- if (overrides == null)
- overrides = new HashMap();
- if ((other.flags & DEFERRED) == 0 ||
- overrides.get(member) == null)
- overrides.put(member, other);
- }
- }
+ checkOverride(pos, clazz, it.next(), overrides);
}
}
- if (overrides != null) {
- for (Iterator/*<Symbol>*/ it = overrides.keySet().iterator();
- it.hasNext();) {
- Symbol member = (Symbol) it.next();
- Symbol other = (Symbol) overrides.get(member);
- if ((other.flags & DEFERRED) != 0) {
- abstractClassError(
- clazz, member + member.locationString() +
- " is marked `override' and overrides only abstract members" + other + other.locationString());
+ for (Iterator/*<Symbol>*/ it = overrides.keySet().iterator();
+ it.hasNext();) {
+ Symbol member = (Symbol) it.next();
+ Symbol other = (Symbol) overrides.get(member);
+ if ((other.flags & DEFERRED) != 0) {
+ abstractClassError(
+ clazz, member + member.locationString() +
+ " is marked `override' and overrides only abstract members" + other + other.locationString());
+ }
+ }
+ }
+
+ void checkOverride(int pos, Symbol clazz, Symbol other,
+ HashMap/*<Symbol,Symbol>*/ overrides) {
+ Symbol member = other;
+ if ((other.flags & PRIVATE) == 0) {
+ Symbol member1 = clazz.info().lookup(other.name);
+ if (member1.kind != NONE && member1.owner() != other.owner()) {
+ 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 (member == other)
+ member = alts[i];
+ else
+ unit.error(
+ pos,
+ "ambiguous override: both " +
+ member + ":" + normalizedInfo(self, member) +
+ "\n and " + alts[i] + ":" + normalizedInfo(self, alts[i]) +
+ "\n override " + other + ":" + otherinfo +
+ other.locationString());
+ }
+ }
+ break;
+ default:
+ member = member1;
}
}
}
+ if (member != other) {
+ checkOverride(pos, clazz, member, other);
+ }
+ if (clazz.kind == CLASS && (clazz.flags & ABSTRACTCLASS) == 0) {
+ if ((member.flags & DEFERRED) != 0) {
+ abstractClassError(
+ clazz,
+ 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 &&
+ ((other.flags & DEFERRED) == 0 ||
+ overrides.get(member) == null))
+ overrides.put(member, other);
+ }
}
//where
private void abstractClassError(Symbol clazz, String msg) {
@@ -116,32 +138,6 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
clazz.flags |= ABSTRACTCLASS;
}
- Symbol findOverriding(int pos, Symbol clazz, Symbol members, Symbol other) {
- Type self = clazz.thisType();
- Symbol member = members;
- Type memberinfo = normalizedInfo(self, member);
- Type otherinfo = normalizedInfo(self, other);
- switch (memberinfo) {
- case OverloadedType(Symbol[] alts, Type[] alttypes):
- for (int i = 0; i < alts.length; i++) {
- if (alttypes[i].isSubType(otherinfo)) {
- if (member == members) {
- member = alts[i];
- memberinfo = alttypes[i];
- } else {
- unit.error(
- pos,
- "ambiguous override: both " +
- member + ":" + memberinfo +
- "\n and " + alts[i] + ":" + alttypes[i] +
- "\n override " + other + ":" + otherinfo +
- other.locationString());
- }
- }
- }
- }
- return member;
- }
/** Check that all conditions for overriding `other' by `member' are met.
* That is for overriding member M and overridden member O:
@@ -232,7 +228,10 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
Type normalizedInfo(Type site, Symbol sym) {
Type tp = site.memberInfo(sym);
- if (sym.kind == VAL && (sym.flags & STABLE) != 0) tp = tp.resultType();
+ switch (tp) {
+ case PolyType(Symbol[] tparams, Type restp):
+ if (tparams.length == 0) return restp;
+ }
return tp;
}