diff options
Diffstat (limited to 'sources/scalac/typechecker')
-rw-r--r-- | sources/scalac/typechecker/Analyzer.java | 29 | ||||
-rw-r--r-- | sources/scalac/typechecker/DeSugarize.java | 25 | ||||
-rw-r--r-- | sources/scalac/typechecker/Infer.java | 82 |
3 files changed, 73 insertions, 63 deletions
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 5190f2da97..f4d2ed8fa0 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -213,9 +213,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { // Name resolution ----------------------------------------------------------- String decode(Name name) { - if (name.isTypeName()) return "type " + name; - else if (name.isConstrName()) return "constructor " + name; - else return "value " + name.toString(); + if (name.isTypeName()) return "type " + NameTransformer.decode(name); + else if (name.isConstrName()) return "constructor " + NameTransformer.decode(name); + else return "value " + NameTransformer.decode(name); } /** Is `sym' accessible as a member of tree `site' in current context? @@ -692,9 +692,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { */ int flip(Symbol base, Symbol tvar) { Symbol clazz = tvar.owner().primaryConstructorClass(); - Symbol sym = clazz; + Symbol sym = base; int flip = CoVariance; while (sym != clazz && flip != AnyVariance) { + //System.out.println("flip: " + sym + " " + sym.isParameter());//DEBUG if (sym.isParameter()) flip = -flip; else if (sym.owner().kind != CLASS) flip = AnyVariance; else if (sym.kind == ALIAS) flip = NoVariance; @@ -723,10 +724,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { if (sym.variance() != 0) { int f = flip(base, sym); if (f != AnyVariance && sym.variance() != f * variance) { - error(sym.pos, + //System.out.println("flip(" + base + "," + sym + ") = " + f);//DEBUG + error(base.pos, varianceString(sym.variance()) + " " + sym + - " occurs in " + f * variance + - " position in type " + all); + " occurs in " + varianceString(f * variance) + + " position in type " + all + " of " + base); } } validateVariance(base, all, pre, variance); @@ -753,7 +755,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { void validateVariance(Symbol base, Type all, Type[] tps, int variance, Symbol[] tparams) { for (int i = 0; i < tps.length; i++) - validateVariance(base, all, tps[i], variance * tparams[i].variance()); + if (tps[i] != tparams[i].type()) + validateVariance(base, all, tps[i], variance * tparams[i].variance()); } // Entering Symbols ---------------------------------------------------------- @@ -1108,8 +1111,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { // enter all members Scope members = new Scope(); pushContext(templ, clazz, members); - if ((clazz.flags & CASE) != 0) - templ.body = desugarize.addCaseMethods(templ.body, clazz, parents); templ.body = desugarize.Statements(templ.body, false); enterSyms(templ.body); popContext(); @@ -1954,11 +1955,15 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { case TypeDef(_, _, Tree rhs, Tree lobound): pushContext(tree, sym, new Scope(context.scope)); int mode = TYPEmode; - if (sym.kind == ALIAS) mode |= FUNmode; + int variance = CoVariance; + if (sym.kind == ALIAS) { + mode |= FUNmode; + variance = NoVariance; + } Tree rhs1 = transform(rhs, mode); Tree lobound1 = transform(lobound, TYPEmode); popContext(); - validateVariance(sym, sym.info(), NoVariance); + validateVariance(sym, sym.info(), variance); return copy.TypeDef(tree, sym, rhs1, lobound1) .setType(definitions.UNIT_TYPE); diff --git a/sources/scalac/typechecker/DeSugarize.java b/sources/scalac/typechecker/DeSugarize.java index 07c2e4a234..fdf4b0b542 100644 --- a/sources/scalac/typechecker/DeSugarize.java +++ b/sources/scalac/typechecker/DeSugarize.java @@ -701,31 +701,6 @@ public class DeSugarize implements Kinds, Modifiers { return stats.toArray(); } - /** Does list of types inherit from class scala.Algebraic? - */ - boolean inheritsAlgebraic(Type[] tps) { - Type algebraic = global.definitions.getType(Names.scala_Algebraic); - for (int i = 0; i < tps.length; i++) { - if (tps[i].isSubType(algebraic)) return true; - } - return false; - } - - /** Add toString, hashCode and == if class inherts from scala.Algebraic. - */ - Tree[] addCaseMethods(Tree[] body, Symbol clazz, Type[] parents) { - if (inheritsAlgebraic(parents)) { - /* todo uncomment and implement - TreeList stats = new TreeList(body); - Symbol[] params = clazz.constructor().firstParams(); - stats.append(toStringMethod(clazz, params)); - stats.append(hashcodeMethod(clazz, params)); - stats.append(equalsMethod(clazz, params)); - */ - } - return body; - } - //debug void print(Tree tree, String conv, Tree result) { if (global.log()) { diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java index ab8c98e544..0ccbcc1e8d 100644 --- a/sources/scalac/typechecker/Infer.java +++ b/sources/scalac/typechecker/Infer.java @@ -214,7 +214,6 @@ public class Infer implements Modifiers, Kinds { } } - /** Do type arguments `targs' conform to formal parameters `tparams'? */ private boolean isWithinBounds(Symbol[] tparams, Type[] targs) { @@ -298,14 +297,47 @@ public class Infer implements Modifiers, Kinds { private void minimizeVar(Type tp) { switch (tp) { case TypeVar(Type origin, Type.Constraint constr): - if (constr.inst == Type.NoType && constr.lobounds != Type.List.EMPTY) - constr.inst = Type.lub(constr.lobounds.toArray()); + if (constr.inst == Type.NoType) + if (constr.lobounds != Type.List.EMPTY) { + constr.inst = Type.lub(constr.lobounds.toArray()); + } else { + constr.inst = global.definitions.ALL_TYPE; + } return; default: throw new ApplicationError(); } } + private void maximizeVars(Symbol[] tparams, Type[] tvars, int i) + throws NoInstance { + if (tvars[i] != Type.NoType) { + switch (tvars[i]) { + case TypeVar(Type origin, Type.Constraint constr): + if (constr.inst != Type.NoType) { + constr.inst = tvars[i] = instantiate(constr.inst); + } else { + Type tvar = tvars[i]; + tvars[i] = Type.NoType; + Type bound = tparams[i].info(); + boolean cyclic = false; + for (int j = 0; j < tvars.length; j++) { + if (bound.contains(tparams[j])) { + cyclic |= tvars[j] == Type.NoType; + maximizeVars(tparams, tvars, j); + } + } + if (!cyclic) + constr.hibounds = new Type.List( + bound.subst(tparams, tvars), constr.hibounds); + maximizeVar(tvar); + tvars[i] = ((Type.TypeVar) tvar).constr.inst; + } + if (tvars[i] == Type.AnyType) tvars[i] = definitions.ANY_TYPE; + } + } + } + private Type[] freshVars(Symbol[] tparams) { Type[] tvars = new Type[tparams.length]; for (int i = 0; i < tvars.length; i++) { @@ -373,7 +405,7 @@ public class Infer implements Modifiers, Kinds { * If no maximal type variables exists that make the * instantiated type a subtype of `pt' and `lastTry' is true, return `null'. */ - private Type[] instTypeArgs(Symbol[] tparams, Type restype, Type pt) { + private Type[] exprTypeArgs(Symbol[] tparams, Type restype, Type pt) { Type[] tvars = freshVars(tparams); // add all bounds except F-bounds to upper bounds of type variable. for (int i = 0; i < tvars.length; i++) { @@ -389,7 +421,7 @@ public class Infer implements Modifiers, Kinds { try { Type[] targs = new Type[tvars.length]; for (int i = 0; i < tvars.length; i++) { - maximizeVar(tvars[i]); + minimizeVar(tvars[i]); targs[i] = instantiate(tvars[i]); } return targs; @@ -399,7 +431,7 @@ public class Infer implements Modifiers, Kinds { return null; } - /** As before, but: don't maximize. Instead map all unistantiated + /** As before, but: don't minimize. Instead map all unistantiated * type vars to AnyType. */ public Type[] protoTypeArgs(Symbol[] tparams, Type restype, Type pt, @@ -556,7 +588,8 @@ public class Infer implements Modifiers, Kinds { Type[] targs = new Type[tvars.length]; for (int i = 0; i < tvars.length; i++) { minimizeVar(tvars[i]); - targs[i] = (((Type.TypeVar) tvars[i]).constr.inst == Type.NoType) + Type instType = ((Type.TypeVar) tvars[i]).constr.inst; + targs[i] = (instType == Type.NoType || instType == global.definitions.ALL_TYPE) ? Type.NoType : instantiate(tvars[i]); } @@ -611,9 +644,9 @@ public class Infer implements Modifiers, Kinds { return argumentTypeInstance(tparams2, restype1, pt1, pt2); default: if (tparams.length != 0) { - Type[] targs = instTypeArgs(tparams, restype, pt1); + Type[] targs = exprTypeArgs(tparams, restype, pt1); if (targs == null) - targs = instTypeArgs(tparams, restype, pt2); + targs = exprTypeArgs(tparams, restype, pt2); if (targs == null) throw new Type.Error( typeErrorMsg( @@ -639,7 +672,7 @@ public class Infer implements Modifiers, Kinds { System.arraycopy(tparams1, 0, tparams2, tparams.length, tparams1.length); return exprInstance(tree, tparams2, restype1, pt); } - Type[] targs = instTypeArgs(tparams, restype, pt); + Type[] targs = exprTypeArgs(tparams, restype, pt); if (targs == null) throw new Type.Error( "polymorphic expression of type " + tree.type + @@ -703,23 +736,20 @@ public class Infer implements Modifiers, Kinds { Type restype1 = restype.subst(tparams, tvars); Type ctpe1 = restype1.resultType(); if (ctpe1.isSubType(pt)) { - Type[] targs = new Type[tparams.length]; - for (int i = 0; i < tvars.length; i++) { - try { - targs[i] = instantiateUpper(tvars[i], true); - if (targs[i] == Type.AnyType) - targs[i] = definitions.ANY_TYPE; - } catch (NoInstance ex) { - throw new Type.Error( - "constructor of type " + ctpe1 + - " can be instantiated in more than one way to expected type " + - pt + - "\n --- because ---\n" + ex.getMessage()); + try { + for (int i = 0; i < tvars.length; i++) { + maximizeVars(tparams, tvars, i); } + checkBounds(tparams, tvars, "inferred "); + tree.setType(restype.subst(tparams, tvars)); + //System.out.println("inferred constructor type: " + tree.type);//DEBUG + } catch (NoInstance ex) { + throw new Type.Error( + "constructor of type " + ctpe1 + + " can be instantiated in more than one way to expected type " + + pt + + "\n --- because ---\n" + ex.getMessage()); } - checkBounds(tparams, targs, "inferred "); - tree.setType(restype.subst(tparams, targs)); - //System.out.println("inferred constructor type: " + tree.type);//DEBUG } else { throw new Type.Error( typeErrorMsg( @@ -749,7 +779,7 @@ public class Infer implements Modifiers, Kinds { Symbol[] uninstantiated = normalizeArgs(targs, tparams); return isWithinBounds(tparams, targs) && - instTypeArgs(uninstantiated, restpe.subst(tparams, targs), pt) + exprTypeArgs(uninstantiated, restpe.subst(tparams, targs), pt) != null; } } catch (NoInstance ex) { |