From 67b84045bfcd7badbc6e397d7f597028c9f11eea Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 7 Mar 2003 11:58:24 +0000 Subject: *** empty log message *** --- sources/scalac/symtab/Symbol.java | 4 +- sources/scalac/symtab/Type.java | 12 +++--- sources/scalac/typechecker/Analyzer.java | 52 ++++++++++++++++++------ sources/scalac/typechecker/DeSugarize.java | 63 +++++++++++++++++------------- sources/scalac/typechecker/Infer.java | 17 ++++---- 5 files changed, 94 insertions(+), 54 deletions(-) (limited to 'sources/scalac') diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index 4f78b26978..a2399fda32 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -154,7 +154,9 @@ public abstract class Symbol implements Modifiers, Kinds { /** Does this symbol denote a stable value? */ public final boolean isStable() { - return kind == VAL && (flags & MUTABLE) == 0 && type().isObjectType(); + return kind == VAL && + ((flags & STABLE) != 0 || + (flags & MUTABLE) == 0 && type().isObjectType()); } /** Does this symbol denote a variable? */ diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 0f5a7ac6d4..5c7790fb72 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -139,7 +139,7 @@ public class Type implements Modifiers, Kinds, TypeTags { public Type widen() { if (definedId != Global.instance.currentPhase.id) { definedId = Global.instance.currentPhase.id; - tp = pre.memberType(sym).widen(); + tp = pre.memberType(sym).resultType().widen(); } return tp; } @@ -372,7 +372,7 @@ public class Type implements Modifiers, Kinds, TypeTags { } } - /** The arity of the first parameter section of this type. + /** The first parameter section of this type. */ public Symbol[] firstParams() { switch (this) { @@ -852,7 +852,7 @@ public class Type implements Modifiers, Kinds, TypeTags { Symbol sym = symbol(); Symbol ownclass = sym.owner().primaryConstructorClass(); if (ownclass.isSubClass(clazz) && - pre.symbol().isSubClass(ownclass)) { + pre.widen().symbol().isSubClass(ownclass)) { switch (pre.baseType(ownclass)) { case TypeRef(_, Symbol basesym, Type[] baseargs): Symbol[] baseparams = basesym.typeParams(); @@ -874,7 +874,7 @@ public class Type implements Modifiers, Kinds, TypeTags { Type toPrefix(Type pre, Symbol clazz) { if (pre == NoType || clazz.kind != CLASS) return this; - else if (symbol().isSubClass(clazz) && pre.symbol().isSubClass(symbol())) + else if (symbol().isSubClass(clazz) && pre.widen().symbol().isSubClass(symbol())) return pre; else return toPrefix(pre.baseType(clazz).prefix(), clazz.owner()); @@ -916,7 +916,7 @@ public class Type implements Modifiers, Kinds, TypeTags { private Type memberTransform(Symbol sym, Type tp) { Type tp1 = tp.asSeenFrom(this, sym.owner()); - //if (Global.instance.debug) System.out.println(this + ".memberType(" + sym + ":" + tp + ") = " + tp1);//debug + //if (Global.instance.debug) System.out.println(this + ".memberType(" + sym + ":" + tp + ") = " + tp1);//DEBUG return tp1; } @@ -2111,7 +2111,7 @@ public class Type implements Modifiers, Kinds, TypeTags { case CovarType(Type tp): return "+" + tp; case OverloadedType(Symbol[] alts, Type[] alttypes): - return " " + ArrayApply.toString(alttypes, "", " ", "");//debug + return ArrayApply.toString(alttypes, "", " ", ""); case TypeVar(Type origin, Constraint constr): if (constr.inst != NoType) return constr.inst.toString(); else return origin + "?"; diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index fe6a0b13d5..b4193f828c 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -184,7 +184,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { void reportTypeError(int pos, Type.Error ex) { if (ex instanceof CyclicReference) { - if (global.debug) ex.printStackTrace();//DEBUG + if (global.debug) ex.printStackTrace(); CyclicReference cyc = (CyclicReference) ex; if (cyc.info instanceof LazyTreeType) { switch (((LazyTreeType) cyc.info).tree) { @@ -547,7 +547,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { it.hasNext();) { Symbol other = it.next(); Symbol member = clazz.info().lookup(other.name); - if (other != member && member.kind != NONE) + if (other != member && (other.flags & PRIVATE) == 0 && + member.kind != NONE) checkOverride(clazz, member, other); if ((member.flags & DEFERRED) != 0 && clazz.kind == CLASS && @@ -582,7 +583,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { overrideError(pos, member, other, "cannot override final member"); } else if ((other.flags & DEFERRED) == 0 && ((member.flags & OVERRIDE) == 0)) { overrideError(pos, member, other, "needs `override' modifier"); - } else if ((other.flags & STABLE) != 0 && ((member.flags & STABLE) == 0)) { + } else if (other.isStable() && !member.isStable()) { overrideError(pos, member, other, "needs to be an immutable value"); } else { Type self = clazz.thisType(); @@ -803,7 +804,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { sym.setInfo(Type.ErrorType); throw new CyclicReference(sym, Type.NoType); } - ((ClassDef) tree).mods |= LOCKED; pushContext(tree, sym.constructor(), new Scope(context.scope)); @@ -881,6 +881,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } popContext(); owntype = makeMethodType(tparamSyms, vparamSyms, restpe); + //System.out.println("methtype " + name + ":" + owntype);//DEBUG break; case TypeDef(int mods, Name name, Tree rhs): @@ -914,6 +915,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { if (global.debug) System.out.println("defined " + sym);//debug } catch (Type.Error ex) { reportTypeError(tree.pos, ex); + tree.type = Type.ErrorType; } this.unit = savedUnit; @@ -1033,7 +1035,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { // System.out.println("name = " + name + ", pos = " + tree.pos + ", importlist = ");//DEBUG // for (ImportList imp = nextimports; imp != null; imp = imp.prev) { -// new TextTreePrinter().print(" ").print(imp.tree).println().end();//debug +// new TextTreePrinter().print(" ").print(imp.tree).println().end();//DEBUG // } while (nextimports != null && nextimports.tree.pos >= tree.pos) { @@ -1083,8 +1085,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { tree = make.Select(tree.pos, qual, name); } symtype = pre.memberType(sym); - if ((pt != null && pt.isStable() || (mode & QUALmode) != 0) - && sym.isStable()) { + if ((pt != null && pt.isStable() || (mode & QUALmode) != 0) && sym.isStable()) { //System.out.println("making single " + sym + ":" + symtype);//DEBUG symtype = Type.singleType(pre, sym); } @@ -1259,6 +1260,30 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { argMode = PATTERNmode; } + // if function is overloaded with one alternative whose arity matches + // argument length, preselect this alternative. + switch (fn1.type) { + case OverloadedType(Symbol[] alts, Type[] alttypes): + int matching1 = -1; + int matching2 = -1; + for (int i = 0; i < alttypes.length; i++) { + Type alttp = alttypes[i]; + switch (alttp) { + case PolyType(_, Type restp): alttp = restp; + } + switch (alttp) { + case MethodType(Symbol[] params, _): + if (params.length == args.length || + params.length == 1 && (params[0].flags & REPEATED) != 0) { + matching2 = matching1; + matching1 = i; + } + } + } + if (matching1 >= 0 && matching2 < 0) + fn1.setSymbol(alts[matching1]).setType(alttypes[matching1]); + } + // handle the case of application of match to a visitor specially if (args.length == 1 && args[0] instanceof Visitor) { Type pattp = matchQualType(fn1); @@ -1337,7 +1362,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { if (fn1.type == Type.ErrorType) return tree.setType(Type.ErrorType); - new TextTreePrinter().print(tree).println().end();//debug + //new TextTreePrinter().print(tree).println().end();//DEBUG return error(tree, infer.applyErrorMsg( "", fn1, " cannot be applied to ", argtypes, pt)); @@ -1420,8 +1445,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { args[i] = transform(args[i], argMode, Type.AnyType); argtypes[i] = args[i].type; } + return argtypes; } - return argtypes; } /** Atribute an expression or pattern with prototype `pt'. @@ -1662,6 +1687,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Tree rhs1 = rhs; if (tpe1 == Tree.Empty) { tpe1 = gen.mkType(rhs1.pos, rhs.type); + //System.out.println("infer " + sym + ":" + rhs.type);//DEBUG // rhs already attributed by defineSym in this case } else if (rhs != Tree.Empty) { if ((mods & CASE) != 0) { @@ -1685,7 +1711,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Tree rhs1 = rhs; if (tpe1 == Tree.Empty) { tpe1 = gen.mkType(rhs1.pos, rhs1.type); - // rhs already attributed by defineSym in this case + //System.out.println("infer " + sym + ":" + rhs.type);//DEBUG + //rhs already attributed by defineSym in this case } else if (rhs != Tree.Empty) { rhs1 = transform(rhs, EXPRmode, tpe1.type == Type.NoType ? Type.AnyType : tpe1.type); @@ -2000,7 +2027,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { case SingletonType(Tree ref): Tree ref1 = transform(ref, EXPRmode, Type.AnyType); return make.TypeTerm(tree.pos) - .setType(checkObjectType(tree.pos, ref1.type)); + .setType(checkObjectType(tree.pos, ref1.type.resultType())); case SelectFromType(Tree qual, Name name): Tree qual1 = transform(qual, TYPEmode); @@ -2067,6 +2094,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } } catch (Type.Error ex) { reportTypeError(tree.pos, ex); + tree.type = Type.ErrorType; return tree; } } @@ -2104,7 +2132,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { this.c = context; } public void complete(Symbol sym) { - //System.out.println("completing " + sym);//debug + //System.out.println("completing " + sym);//DEBUG //if (sym.isConstructor()) sym.constructorClass().initialize(); //else if (sym.isModule()) sym.moduleClass().initialize(); defineSym(tree, u, i, c); diff --git a/sources/scalac/typechecker/DeSugarize.java b/sources/scalac/typechecker/DeSugarize.java index 929d2c7275..1a9677e27e 100644 --- a/sources/scalac/typechecker/DeSugarize.java +++ b/sources/scalac/typechecker/DeSugarize.java @@ -387,7 +387,7 @@ public class DeSugarize implements Kinds, Modifiers { change = true; break; case ValDef(int mods, _, _, _): - change = !isLocal && (mods & MUTABLE) != 0; + change = !isLocal; } } if (change) { @@ -395,12 +395,12 @@ public class DeSugarize implements Kinds, Modifiers { for (int i = 0; i < stats.length; i++) { switch (stats[i]) { case PatDef(_, _, _): - ts.append(this.PatDef(stats[i])); + ts.append(Statements(this.PatDef(stats[i]), isLocal)); break; - case ValDef(int mods, _, _, _): - if (!isLocal && (mods & MUTABLE) != 0) - ts.append(this.VarDef(stats[i])); - else + case ValDef(_, _, _, _): + if (!isLocal) { + ts.append(this.ValDef(stats[i])); + } else ts.append(stats[i]); break; default: @@ -498,33 +498,40 @@ public class DeSugarize implements Kinds, Modifiers { } } - public Tree[] VarDef(Tree tree) { + public Tree[] ValDef(Tree tree) { switch (tree) { case ValDef(int mods, Name name, Tree tpe, Tree rhs): - Name varname = Name.fromString(name + "$"); - Tree vardef1 = copy.ValDef( - tree, PRIVATE | MUTABLE | SYNTHETIC, varname, tpe, rhs); + Name valname = Name.fromString(name + "$"); + Tree valdef1 = copy.ValDef( + tree, (mods & (DEFERRED | MUTABLE | CASE | MODUL)) | PRIVATE, + valname, tpe, rhs); + int mods1 = mods | ACCESSOR; + if ((mods1 & MUTABLE) == 0) mods1 |= STABLE; Tree getter = make.DefDef( - tree.pos, mods | ACCESSOR, name, - Tree.ExtTypeDef.EMPTY_ARRAY, - Tree.ExtValDef.EMPTY_ARRAY_ARRAY, + tree.pos, mods1, name, + Tree.ExtTypeDef.EMPTY_ARRAY, Tree.ExtValDef.EMPTY_ARRAY_ARRAY, tpe, ((mods & DEFERRED) != 0) ? Tree.Empty - : make.Ident(tree.pos, varname)); - Tree setter = make.DefDef( - tree.pos, mods | ACCESSOR, setterName(name), - Tree.ExtTypeDef.EMPTY_ARRAY, - new ValDef[][]{{ - (ValDef) make.ValDef( - tree.pos, SYNTHETIC, parameterName(0), tpe, Tree.Empty)}}, - gen.mkType(tree.pos, global.definitions.UNIT_TYPE), - ((mods & DEFERRED) != 0) ? Tree.Empty - : make.Assign( - tree.pos, - make.Ident(tree.pos, varname), - make.Ident(tree.pos, parameterName(0)))); - if ((mods & DEFERRED) != 0) return new Tree[]{getter, setter}; - else return new Tree[]{vardef1, getter, setter}; + : make.Ident(tree.pos, valname)); + if ((mods1 & MUTABLE) == 0) { + if ((mods1 & DEFERRED) != 0) return new Tree[]{getter}; + else return new Tree[]{valdef1, getter}; + } else { + Tree setter = make.DefDef( + tree.pos, mods1, setterName(name), + Tree.ExtTypeDef.EMPTY_ARRAY, + new ValDef[][]{{ + (ValDef) make.ValDef( + tree.pos, SYNTHETIC, parameterName(0), tpe, Tree.Empty)}}, + gen.mkType(tree.pos, global.definitions.UNIT_TYPE), + ((mods1 & DEFERRED) != 0) ? Tree.Empty + : make.Assign( + tree.pos, + make.Ident(tree.pos, valname), + make.Ident(tree.pos, parameterName(0)))); + if ((mods1 & DEFERRED) != 0) return new Tree[]{getter, setter}; + else return new Tree[]{valdef1, getter, setter}; + } default: throw new ApplicationError(); } diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java index c788a368da..9da7ef13d8 100644 --- a/sources/scalac/typechecker/Infer.java +++ b/sources/scalac/typechecker/Infer.java @@ -398,14 +398,17 @@ public class Infer implements Modifiers, Kinds { Type insttype = restype.subst(tparams, tvars); Type[] targs = new Type[tvars.length]; if (isCompatible(insttype, pt)) { - for (int i = 0; i < tvars.length; i++) { - targs[i] = instantiateUpper(tvars[i], isCovariant(tparams[i], params)); - } - } else { - for (int i = 0; i < tvars.length; i++) { - targs[i] = Type.AnyType; + try { + for (int i = 0; i < tvars.length; i++) { + targs[i] = instantiateUpper(tvars[i], isCovariant(tparams[i], params)); + } + return targs; + } catch (NoInstance ex) { } } + for (int i = 0; i < tvars.length; i++) { + targs[i] = Type.AnyType; + } return targs; } @@ -824,7 +827,7 @@ public class Infer implements Modifiers, Kinds { } if (i < alttypes.length) { for (int j = i + 1; j < alttypes.length; j++) { - if (alts[i].isValue() && alttypes[i].typeParams().length == nparams) + if (alts[j].isValue() && alttypes[j].typeParams().length == nparams) throw new Type.Error(overloadResolveErrorMsg( alts[i], alttypes[i], alts[j], alttypes[j])); } -- cgit v1.2.3