diff options
Diffstat (limited to 'sources/scalac')
-rw-r--r-- | sources/scalac/symtab/Definitions.java | 2 | ||||
-rw-r--r-- | sources/scalac/symtab/Symbol.java | 2 | ||||
-rw-r--r-- | sources/scalac/transformer/UnCurry.java | 88 | ||||
-rw-r--r-- | sources/scalac/transformer/UnCurryPhase.java | 2 | ||||
-rw-r--r-- | sources/scalac/util/Names.java | 2 |
5 files changed, 88 insertions, 8 deletions
diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index 7d0d6ce0a7..9f4ff9cbe0 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -707,7 +707,7 @@ public class Definitions { // ANY_PLUS = newMethod(ANY_CLASS,Names.PLUS ,Modifiers.FINAL); ANY_IS = newMethod(ANY_CLASS,Names.isInstanceOf,Modifiers.FINAL); ANY_AS = newMethod(ANY_CLASS,Names.asInstanceOf,Modifiers.FINAL); - ANY_MATCH = newMethod(ANY_CLASS,Names.match ,Modifiers.FINAL); + ANY_MATCH = newMethod(ANY_CLASS,Names._match ,Modifiers.FINAL); initMethod(ANY_EQEQ , new Type[]{ANY_TYPE()} , boolean_TYPE()); initMethod(ANY_BANGEQ , new Type[]{ANY_TYPE()} , boolean_TYPE()); diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index 6c5ef821d0..5c518bc65c 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -1227,7 +1227,7 @@ public abstract class Symbol implements Modifiers, Kinds { private Type transformInfo(Phase phase, Type info) { Global global = phase.global; Phase current = global.currentPhase; - boolean keepInheritedOverloaded = current.id <= global.PHASE.REFCHECK.id(); + boolean keepInheritedOverloaded = current.id <= global.PHASE.UNCURRY.id(); switch (info) { case ErrorType: case NoType: diff --git a/sources/scalac/transformer/UnCurry.java b/sources/scalac/transformer/UnCurry.java index cf2cc46afc..0deb9fc3fc 100644 --- a/sources/scalac/transformer/UnCurry.java +++ b/sources/scalac/transformer/UnCurry.java @@ -123,11 +123,14 @@ public class UnCurry extends OwnerTransformer } switch (tree) { case ClassDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl): + Symbol clazz = tree.symbol(); + for (Scope.SymbolIterator it = clazz.members().iterator(); it.hasNext(); ) + checkNoDoubleDef(clazz, it.next()); return copy.ClassDef( - tree, tree.symbol(), tparams, - uncurry(transform(vparams, tree.symbol())), + tree, clazz, tparams, + uncurry(transform(vparams, clazz)), tpe, - transform(impl, tree.symbol())); + transform(impl, clazz)); case DefDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs): Symbol sym = tree.symbol(); @@ -173,7 +176,7 @@ public class UnCurry extends OwnerTransformer !(args1[0] instanceof Tree.Visitor)) { switch (TreeInfo.methPart(fn1)) { case Select(Tree qual, Name name): - assert name == Names.match; + assert name == Names._match; return gen.postfixApply(qual, args1[0], currentOwner); default: throw new ApplicationError("illegal prefix for match: " + tree); @@ -324,4 +327,81 @@ public class UnCurry extends OwnerTransformer return transform(arg); } } + +// Double Definition Checking ----------------------------------------------- + + private void checkNoDoubleDef(Symbol clazz, Symbol sym) { + switch (sym.type()) { + case OverloadedType(Symbol[] alts, Type[] alttypes): + for (int i = 0; i < alttypes.length; i++) { + for (int j = i + 1; j < alttypes.length; j++) + if (inConflict(alts[i], alts[j], descr.uncurry(alttypes[i]), descr.uncurry(alttypes[j]))) + conflictError(clazz, alts[i], alts[j], alttypes[i], alttypes[j]); + } + break; + default: + } + } + + private void conflictError(Symbol clazz, Symbol sym1, Symbol sym2, Type type1, Type type2) { + if (sym1.owner() == clazz && sym2.owner() == clazz) + unit.error(sym2.pos, + "Double declaration:\n" + + sym1 + ": " + type1 + " and\n" + + sym2 + ": " + type2 + " have same types after erasure"); + else if (sym1.owner() == clazz) + unit.error(sym1.pos, + "Accidental override:\n" + + sym1 + ": " + type1 + " has same type after erasure as\n" + + sym2 + ": " + type2 + " which is inherited from " + sym2.owner()); + else if (sym2.owner() == clazz) + unit.error(sym2.pos, + "Accidental override:\n" + + sym2 + ": " + type2 + " has same type after erasure as\n" + + sym1 + ": " + type1 + " which is inherited from " + sym1.owner()); + else + unit.error(clazz.pos, + "Inheritance conflict: inherited members\n" + + sym1 + ": " + type1 + sym1.locationString() + " and\n" + + sym2 + ": " + type2 + sym2.locationString() + " have same types after erasure"); + } + + private boolean inConflict(Symbol sym1, Symbol sym2, Type type1, Type type2) { + switch (type1) { + case PolyType(_, Type restype1): + return inConflict(sym1, sym2, restype1, type2); + + case MethodType(Symbol[] params1, Type restype1): + switch (type2) { + case PolyType(_, Type restype2): + return inConflict(sym1, sym2, type1, restype2); + + case MethodType(Symbol[] params2, Type restype2): + if (params1.length != params2.length) return false; + for (int i = 0; i < params1.length; i++) { + if (!params1[i].nextInfo().erasure().isSameAs( + params2[i].nextInfo().erasure())) return false; + } + if (restype1.erasure().isSameAs(restype2.erasure())) + return true; + if (sym1.owner() == sym2.owner()) + return false; + for (int i = 0; i < params1.length; i++) { + if (!params1[i].nextInfo().isSameAs( + params2[i].nextInfo())) return false; + } + return true; + + default: + return false; + } + + default: + switch (type2) { + case PolyType(_, _): + case MethodType(_, _): return inConflict(sym1, sym2, type2, type1); + default: return true; + } + } + } } diff --git a/sources/scalac/transformer/UnCurryPhase.java b/sources/scalac/transformer/UnCurryPhase.java index 44988064de..f94593b9ef 100644 --- a/sources/scalac/transformer/UnCurryPhase.java +++ b/sources/scalac/transformer/UnCurryPhase.java @@ -30,7 +30,7 @@ public class UnCurryPhase extends Phase implements Modifiers { * - if symbol is a def parameter with transformed type T, return () => T */ public Type transformInfo(Symbol sym, Type tp0) { - Type tp1 = uncurry(sym.removeInheritedOverloaded(tp0)); + Type tp1 = uncurry(tp0); if (sym.isDefParameter()) return global.definitions.FUNCTION_TYPE(Type.EMPTY_ARRAY, tp1); else return tp1; } diff --git a/sources/scalac/util/Names.java b/sources/scalac/util/Names.java index 5cc607fa8f..6e93c4f1fb 100644 --- a/sources/scalac/util/Names.java +++ b/sources/scalac/util/Names.java @@ -164,7 +164,7 @@ public class Names { public static final Name java = Name.fromString("java"); public static final Name lang = Name.fromString("lang"); public static final Name length = Name.fromString("length"); - public static final Name match = Name.fromString("match"); + public static final Name _match = Name.fromString("match"); public static final Name map = Name.fromString("map"); public static final Name n = Name.fromString("n"); public static final Name nobinding = Name.fromString("nobinding"); |