diff options
author | Martin Odersky <odersky@gmail.com> | 2003-09-18 10:00:06 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2003-09-18 10:00:06 +0000 |
commit | c0de8fd882c937b7d05368ce0dd5548edea7f839 (patch) | |
tree | 5c744cef4bb771689c8e81c896b337bd43199fa9 | |
parent | 5b9b5356411cbd5e4de94d6c84832f99cd10b5de (diff) | |
download | scala-c0de8fd882c937b7d05368ce0dd5548edea7f839.tar.gz scala-c0de8fd882c937b7d05368ce0dd5548edea7f839.tar.bz2 scala-c0de8fd882c937b7d05368ce0dd5548edea7f839.zip |
*** empty log message ***
-rw-r--r-- | sources/scala/List.scala | 2 | ||||
-rw-r--r-- | sources/scala/Predef.scala | 4 | ||||
-rw-r--r-- | sources/scalac/ast/parser/Parser.java | 26 | ||||
-rw-r--r-- | sources/scalac/symtab/Definitions.java | 2 | ||||
-rw-r--r-- | sources/scalac/symtab/Type.java | 104 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/UnPickle.java | 13 | ||||
-rw-r--r-- | sources/scalac/transformer/UnCurry.java | 72 | ||||
-rw-r--r-- | sources/scalac/typechecker/Analyzer.java | 48 | ||||
-rw-r--r-- | sources/scalac/typechecker/RefCheck.java | 75 | ||||
-rw-r--r-- | sources/scalac/util/Names.java | 1 | ||||
-rw-r--r-- | sources/scalac/util/TypeNames.java | 1 | ||||
-rw-r--r-- | test/files/neg/S6.check | 2 | ||||
-rw-r--r-- | test/files/neg/S7.check | 2 | ||||
-rw-r--r-- | test/files/neg/bug128_129.check | 9 | ||||
-rw-r--r-- | test/files/neg/bug96.check | 3 | ||||
-rw-r--r-- | test/files/neg/matthias2.check | 4 | ||||
-rw-r--r-- | test/neg/S6.check | 2 | ||||
-rw-r--r-- | test/neg/S7.check | 2 | ||||
-rw-r--r-- | test/neg/bug128_129.check | 9 | ||||
-rw-r--r-- | test/neg/bug96.check | 3 | ||||
-rw-r--r-- | test/neg/matthias2.check | 4 |
21 files changed, 252 insertions, 136 deletions
diff --git a/sources/scala/List.scala b/sources/scala/List.scala index c131315a04..8f3e854493 100644 --- a/sources/scala/List.scala +++ b/sources/scala/List.scala @@ -65,7 +65,7 @@ object List { * @return a pair of lists: the first list in the pair contains the list */ def unzip[a,b](l: List[Pair[a,b]]): Pair[List[a], List[b]] = l match { - case Nil => Pair(Nil, Nil) + case Nil => new Pair(Nil, Nil) case Pair(f, s) :: tail => val Pair(fs, ss) = unzip(tail); Pair(f :: fs, s :: ss) diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala index c85835fdf2..fb9386896c 100644 --- a/sources/scala/Predef.scala +++ b/sources/scala/Predef.scala @@ -45,10 +45,10 @@ object Predef { throw new Error(message); } - type Pair[p, q] = Tuple2[p, q]; + type Pair[+p, +q] = Tuple2[p, q]; def Pair[a, b](x: a, y: b) = Tuple2(x, y); - type Triple[a, b, c] = Tuple3[a, b, c]; + type Triple[+a, +b, +c] = Tuple3[a, b, c]; def Triple[a, b, c](x: a, y: b, z: c) = Tuple3(x, y, z); def id[a](x: a): a = x; diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java index cbceab76f4..4f105b5369 100644 --- a/sources/scalac/ast/parser/Parser.java +++ b/sources/scalac/ast/parser/Parser.java @@ -573,7 +573,7 @@ public class Parser implements Tokens { } } - /** MixinQualifier ::= `(' Id `)' + /** MixinQualifier ::= `[' Id `]' */ Name mixinQualifierOpt() { if (s.token == LBRACKET) { @@ -795,10 +795,11 @@ public class Parser implements Tokens { } /** Exprs ::= Expr {`,' Expr} + * | Expr `:' `_' `*' */ Tree[] exprs() { TreeList ts = new TreeList(); - ts.append(expr()); + ts.append(expr(true)); while (s.token == COMMA) { s.nextToken(); ts.append(expr()); @@ -816,12 +817,16 @@ public class Parser implements Tokens { * | return [Expr] * | [SimpleExpr `.'] Id `=' Expr * | SimpleExpr ArgumentExprs `=' Expr - * | PostfixExpr [`:' Type1 | as Type1 | is Type1] + * | PostfixExpr [`:' Type1] * Bindings ::= Id [`:' Type1] * | `(' [Binding {`,' Binding}] `)' * Binding ::= Id [`:' Type] */ Tree expr() { + return expr(false); + } + + Tree expr(boolean isArgument) { if (s.token == IF) { int pos = s.skipToken(); accept(LPAREN); @@ -908,8 +913,19 @@ public class Parser implements Tokens { } } else if (s.token == COLON) { int pos = s.skipToken(); - Tree tp = type1(); - t = make.Typed(pos, t, tp); + if (isArgument && s.token == USCORE) { + int pos1 = s.skipToken(); + if (s.token == IDENTIFIER && s.name == Names.STAR) { + s.nextToken(); + t = make.Typed( + pos, t, make.Ident(pos1, TypeNames.WILDCARD_STAR)); + } else { + syntaxError(s.pos, "`*' expected", true); + } + } else { + Tree tp = type1(); + t = make.Typed(pos, t, tp); + } } if (s.token == ARROW) { t = make.Function(s.skipToken(), convertToParams(t), expr()); diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index a01db7a7ba..cd2299b4e6 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -258,7 +258,7 @@ public class Definitions { SCALA_CLASS, Modifiers.JAVA) .setInfo(JAVA_OBJECT_TYPE); SCALA_CLASS.members().enter(ANYREF_CLASS); - ANYREF_TYPE = ANYREF_CLASS.typeConstructor().unalias(); + ANYREF_TYPE = JAVA_OBJECT_TYPE; ANYREF_CLASS.primaryConstructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, ANYREF_TYPE)); // the scala.OBJECT class diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index acdf8e1d13..d5ba75934b 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -132,8 +132,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { if (pre.isStable() || pre == ErrorType) { return new ExtSingleType(pre, sym); } else { - throw new Type.Error( - "malformed type: " + pre + "#" + sym.nameString() + ".type"); + throw new Type.Malformed(pre, sym.nameString() + ".type"); } } @@ -168,11 +167,11 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { public static Type typeRef(Type pre, Symbol sym, Type[] args) { if (pre.isLegalPrefix() || pre == ErrorType) return TypeRef(pre, sym, args); - else if (sym.kind == ALIAS) - return pre.memberInfo(sym); - else // todo: handle Java-style inner classes - throw new Type.Error( - "malformed type: " + pre + "#" + sym.nameString()); + else if (sym.kind == ALIAS && sym.typeParams().length == args.length) + return sym.info().subst(sym.typeParams(), args) + .asSeenFrom(pre, sym.owner()); + else + throw new Type.Malformed(pre, sym.nameString()); } static class ExtSingleType extends SingleType { @@ -239,21 +238,33 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return syms; } + /** If this is a reference to a type constructor, add its + * type parameters as arguments + */ + public Type withDefaultArgs() { + switch (this) { + case TypeRef(Type pre, Symbol sym, Type[] args): + if (args.length == 0 && sym.typeParams().length != 0) + return TypeRef(pre, sym, Symbol.type(sym.typeParams())); + } + return this; + } + /** The upper bound of this type. Returns always a TypeRef whose * symbol is a class. */ public Type bound() { - switch (this) { + switch (unalias()) { case TypeRef(Type pre, Symbol sym, _): - if (sym.kind == ALIAS) return unalias().bound(); if (sym.kind == TYPE) return pre.memberInfo(sym).bound(); assert sym.isClass() : Debug.show(sym) + " -- " + this; return this; case ThisType(_): case SingleType(_, _): return singleDeref().bound(); - case TypeVar(_, _): - return unalias().bound(); + case TypeVar(Type origin, Constraint constr): + if (constr.inst != NoType) return constr.inst.bound(); + else return this; default: throw Debug.abort("illegal case", this); } @@ -304,10 +315,9 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { /** The thistype or singleton type corresponding to values of this type. */ public Type narrow() { - switch (this) { + switch (unalias()) { case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.kind == ALIAS) return pre.memberInfo(sym).narrow(); - else if (sym.kind == CLASS) return sym.thisType(); + if (sym.kind == CLASS) return sym.thisType(); else return ThisType(sym); case CompoundType(_, _): return symbol().thisType(); @@ -411,7 +421,9 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { throw new Type.Error("alias chain too long (recursive type alias?): " + this); switch (this) { case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.kind == ALIAS) return pre.memberInfo(sym).unalias(n + 1); + if (sym.kind == ALIAS && sym.typeParams().length == args.length) + return sym.info().subst(sym.typeParams(), args) + .asSeenFrom(pre, sym.owner()).unalias(n + 1); break; case TypeVar(Type origin, Constraint constr): if (constr.inst != NoType) return constr.inst.unalias(n + 1); @@ -428,14 +440,13 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { case SingleType(_, _): return singleDeref().parents(); case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.kind == ALIAS) - return unalias().parents(); - else if (sym.kind == CLASS) { + if (sym.kind == CLASS) { assert sym.typeParams().length == args.length : sym + " " + ArrayApply.toString(args) + " " + sym.primaryConstructor().info();//debug return subst(asSeenFrom(sym.info().parents(), pre, sym.owner()), sym.typeParams(), args); - } else + } else { return new Type[]{sym.info().asSeenFrom(pre, sym.owner())}; + } case CompoundType(Type[] parts, _): return parts; default: @@ -593,9 +604,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { case ThisType(_): case SingleType(_, _): case CompoundType(_, _): + case TypeRef(_, _, _): return true; - case TypeRef(Type pre, Symbol sym, _): - return sym.kind != ALIAS || unalias().isObjectType(); default: return false; } @@ -952,8 +962,14 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { case TypeRef(Type pre, Symbol sym, Type[] args): if (sym == clazz) return this; - else if (sym.kind == TYPE || sym.kind == ALIAS) - return pre.memberInfo(sym).baseType(clazz); + else if (sym.kind == TYPE) + return sym.info() + .asSeenFrom(pre, sym.owner()).baseType(clazz); + else if (sym.kind == ALIAS) + if (sym.typeParams().length == args.length) + return sym.info().subst(sym.typeParams(), args) + .asSeenFrom(pre, sym.owner()).baseType(clazz); + else return Type.NoType; else if (clazz.isCompoundSym()) return NoType; else { @@ -983,10 +999,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { public Symbol rebind(Symbol sym) { Symbol sym1 = lookupNonPrivate(sym.name); if (sym1.kind != NONE) { + if ((sym1.flags & LOCKED) != 0) + throw new Type.Error("illegal cyclic reference involving " + sym1); //System.out.println("rebinding " + sym + " to " + sym1);//DEBUG return sym1; } - else return sym; + return sym; } /** A map to implement `asSeenFrom'. @@ -1008,8 +1026,10 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return t.toPrefix(sym, pre, clazz); case TypeRef(Type prefix, Symbol sym, Type[] args): - if (sym.kind == ALIAS) { - return apply(t.unalias()); + if (sym.kind == ALIAS && sym.typeParams().length == args.length) { + return apply( + sym.info().subst(sym.typeParams(), args) + .asSeenFrom(prefix, sym.owner())); } else if (sym.owner().isPrimaryConstructor()) { assert sym.kind == TYPE; Type t1 = t.toInstance(sym, pre, clazz); @@ -1029,7 +1049,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { Type prefix1 = apply(prefix); if (prefix1 == prefix) return t; else return singleType(prefix1, prefix1.rebind(sym)); - } catch (Type.Error ex) {} + } catch (Type.Malformed ex) {} return apply(t.singleDeref()); default: @@ -1668,13 +1688,13 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return true; } - case TypeRef(_, Symbol sym, _): + case TypeRef(_, Symbol sym, Type[] args): switch (that) { case TypeRef(Type pre1, Symbol sym1, _): if (sym1.kind == TYPE && this.isSubType(that.loBound())) return true; } - if (sym.kind == ALIAS) + if (sym.kind == ALIAS && sym.typeParams().length == args.length) return this.unalias().isSubType(that); else if (sym == Global.instance.definitions.ALL_CLASS) return that.isSubType(Global.instance.definitions.ANY_TYPE); @@ -1693,8 +1713,9 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } switch (that) { - case TypeRef(_, Symbol sym1, _): - if (sym1.kind == ALIAS) return this.isSubType(that.unalias()); + case TypeRef(_, Symbol sym1, Type[] args): + if (sym1.kind == ALIAS && sym1.typeParams().length == args.length) + return this.isSubType(that.unalias()); break; } @@ -1920,8 +1941,9 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { switch (this) { case NoType: return false; - case TypeRef(_, Symbol sym, _): - if (sym.kind == ALIAS) return this.unalias().isSameAs(that); + case TypeRef(_, Symbol sym, Type[] args): + if (sym.kind == ALIAS && sym.typeParams().length == args.length) + return this.unalias().isSameAs(that); break; case TypeVar(Type origin, Constraint constr): if (constr.inst != NoType) return constr.inst.isSameAs(that); @@ -1929,8 +1951,9 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } switch (that) { - case TypeRef(_, Symbol sym, _): - if (sym.kind == ALIAS) return this.isSameAs(that.unalias()); + case TypeRef(_, Symbol sym, Type[] args): + if (sym.kind == ALIAS && sym.typeParams().length == args.length) + return this.isSameAs(that.unalias()); } return false; @@ -2707,7 +2730,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { private Type upperBound() { switch (this) { case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.kind == ALIAS || sym.kind == TYPE) + if (sym.kind == ALIAS && sym.typeParams().length == args.length + || sym.kind == TYPE) return pre.memberInfo(sym).upperBound(); } return this; @@ -2723,7 +2747,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { case TypeRef(Type pre, Symbol sym, Type[] args): switch (sym.kind) { case ALIAS: case TYPE: - return pre.memberInfo(sym).erasure(); + return sym.info().asSeenFrom(pre, sym.owner()).erasure(); case CLASS: if (sym == Global.instance.definitions.UNIT_CLASS) return this; @@ -3010,6 +3034,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } } + public static class Malformed extends Error { + public Malformed(Type pre, String tp) { + super("malformed type: " + pre + "#" + tp); + } + } + /** A class for throwing type errors */ public static class VarianceError extends Error { diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java index e76b9f03cb..22fa3fba78 100644 --- a/sources/scalac/symtab/classfile/UnPickle.java +++ b/sources/scalac/symtab/classfile/UnPickle.java @@ -179,11 +179,14 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { } else { sym = owner.info().lookup(name); if (tag == EXTMODCLASSref) { - switch (sym.type()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - if (alts[i].isModule()) sym = alts[i]; - } + /* + if (sym.kind == VAL) + switch (sym.type()) { + case OverloadedType(Symbol[] alts, _): + for (int i = 0; i < alts.length; i++) + if (alts[i].isModule()) sym = alts[i]; + } + */ assert sym.isModule(); sym = sym.moduleClass(); } diff --git a/sources/scalac/transformer/UnCurry.java b/sources/scalac/transformer/UnCurry.java index eb2ae2c0ce..f7d8ec796f 100644 --- a/sources/scalac/transformer/UnCurry.java +++ b/sources/scalac/transformer/UnCurry.java @@ -25,12 +25,18 @@ public class UnCurry extends OwnerTransformer implements Modifiers { UnCurryPhase descr; + Unit unit; public UnCurry(Global global, UnCurryPhase descr) { super(global); this.descr = descr; } + public void apply(Unit unit) { + super.apply(unit); + this.unit = unit; + } + /** (ps_1) ... (ps_n) => (ps_1, ..., ps_n) */ ValDef[][] uncurry(ValDef[][] params) { @@ -58,6 +64,28 @@ public class UnCurry extends OwnerTransformer } } + /** apply parameterless functions and def parameters + */ + Tree applyDef(Tree tree1) { + assert tree1.symbol() != null : tree1; + switch (tree1.symbol().type()) { + case PolyType(Symbol[] tparams, Type restp): + if (tparams.length == 0 && !(restp instanceof Type.MethodType)) { + return gen.Apply(asMethod(tree1), new Tree[0]); + } else { + return tree1; + } + default: + if (tree1.symbol().isDefParameter()) { + tree1.type = global.definitions.functionType( + Type.EMPTY_ARRAY, tree1.type.widen()); + return gen.Apply(gen.Select(tree1, global.definitions.FUNCTION_APPLY(0))); + } else { + return tree1; + } + } + } + /** - uncurry all symbol and tree types (@see UnCurryPhase) * - for every curried parameter list: (ps_1) ... (ps_n) ==> (ps_1, ..., ps_n) * - for every curried application: f(args_1)...(args_n) ==> f(args_1, ..., args_n) @@ -132,26 +160,18 @@ public class UnCurry extends OwnerTransformer } case Select(_, _): - case Ident(_): - if( TreeInfo.isWildcardPattern( tree ) ) + return applyDef(super.transform(tree)); + + case Ident(Name name): + if (name == TypeNames.WILDCARD_STAR) { + unit.error(tree.pos, " argument does not correspond to `*'-parameter"); return tree; - Tree tree1 = super.transform(tree); - switch (tree1.symbol().type()) { - case PolyType(Symbol[] tparams, Type restp): - if (tparams.length == 0 && !(restp instanceof Type.MethodType)) { - return gen.Apply(asMethod(tree1), new Tree[0]); - } else { - return tree1; - } - default: - if (tree1.symbol().isDefParameter()) { - tree1.type = global.definitions.functionType( - Type.EMPTY_ARRAY, tree1.type.widen()); - return gen.Apply(gen.Select(tree1, global.definitions.FUNCTION_APPLY(0))); - } else { - return tree1; - } + } else if (TreeInfo.isWildcardPattern(tree)) { + return tree; + } else { + return applyDef(super.transform(tree)); } + default: return super.transform(tree); } @@ -170,13 +190,9 @@ public class UnCurry extends OwnerTransformer switch (methtype) { case MethodType(Symbol[] params, _): - if (params.length == 1 && (params[0].flags & REPEATED) != 0) { - assert (args.length != 1 || !(args[0] instanceof Tree.Sequence)); - args = new Tree[]{make.Sequence( pos, args ).setType(params[0].type())}; - + args = toSequence(pos, params, args); } - Tree[] args1 = args; for (int i = 0; i < args.length; i++) { Tree arg = args[i]; @@ -195,6 +211,16 @@ public class UnCurry extends OwnerTransformer else throw new ApplicationError(methtype); } } + private Tree[] toSequence(int pos, Symbol[] params, Tree[] args) { + assert (args.length != 1 || !(args[0] instanceof Tree.Sequence)); + if (args.length == 1) { + switch (args[0]) { + case Typed(Tree arg, Ident(TypeNames.WILDCARD_STAR)): + return new Tree[]{arg}; + } + } + return new Tree[]{make.Sequence( pos, args ).setType(params[0].type())}; + } /** for every argument to a def parameter `def x: T': * if argument is not a reference to a def parameter: diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 05657ba759..8d05fbc465 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -477,10 +477,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { //where private Type.Map checkNoEscapeMap = new Type.Map() { public Type apply(Type t) { - switch (t) { + switch (t.unalias()) { case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.kind == ALIAS) return apply(t.unalias()); - else if (pre instanceof Type.ThisType) checkNoEscape(t, sym); + if (pre instanceof Type.ThisType) checkNoEscape(t, sym); break; case SingleType(ThisType(_), Symbol sym): checkNoEscape(t, sym); @@ -762,9 +761,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { return enterSym(tree, sym); case AliasTypeDef(int mods, Name name, _, _): - return enterSym( - tree, - AliasTypeSymbol.define(tree.pos, name, owner, mods, context.scope)); + Symbol tsym = AliasTypeSymbol.define(tree.pos, name, owner, mods, context.scope); + if (!tsym.primaryConstructor().isInitialized()) + tsym.primaryConstructor().setInfo(new LazyTreeType(tree)); + return enterSym(tree, tsym); case AbsTypeDef(int mods, Name name, _, _): return enterSym( @@ -997,6 +997,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { defineTemplate(templ, clazz, new Scope()); clazz.setInfo(templ.type); ((ModuleDef) tree).tpe = tpe = transform(tpe, TYPEmode); + if (tpe != Tree.Empty) + clazz.setTypeOfThis(new LazySelfType(tpe)); owntype = (tpe == Tree.Empty) ? clazz.type() : tpe.type; break; @@ -1062,12 +1064,12 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs): pushContext(tree, sym.primaryConstructor(), new Scope(context.scope)); Symbol[] tparamSyms = enterParams(tparams); - ((AliasTypeDef) tree).rhs = rhs = transform(rhs, TYPEmode); - owntype = rhs.type; sym.primaryConstructor().setInfo( Type.PolyType(tparamSyms, sym.typeConstructor())); // necessary so that we can access tparams sym.primaryConstructor().flags |= INITIALIZED; + ((AliasTypeDef) tree).rhs = rhs = transform(rhs, TYPEmode); + owntype = rhs.type; popContext(); break; @@ -1220,7 +1222,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } if ((mode & PATTERNmode) != 0) { if (tree.isType()) { - Symbol clazz = tree.type.unalias().symbol(); + Symbol clazz = tree.type.withDefaultArgs().unalias().symbol(); if (clazz.isCaseClass()) { // set type to instantiated case class constructor @@ -1655,9 +1657,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { argpts[i] = formals[i].subst(tparams, targs); // transform arguments with [targs/tparams]formals as prototypes - for (int i = 0; i < args.length; i++) + for (int i = 0; i < args.length; i++) { args[i] = transform( args[i], argMode | POLYmode, formals[i].subst(tparams, targs)); + } // targs1: same as targs except that every AnyType is mapped to // formal parameter type. @@ -1817,6 +1820,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { sym.moduleClass().initialize(); Tree tpe1 = transform(tpe, TYPEmode); Tree.Template templ1 = transformTemplate(templ, sym.moduleClass()); + if (tpe1 != Tree.Empty && !templ1.type.isSubType(tpe1.type)) + error(tree.pos, + sym + " does not implement " + tpe1.type); return copy.ModuleDef(tree, sym, tpe1, templ1) .setType(definitions.UNIT_TYPE); @@ -2098,8 +2104,22 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } case Typed(Tree expr, Tree tpe): - Tree tpe1 = transform(tpe, TYPEmode); - Tree expr1 = transform(expr, mode & baseModes, tpe1.type); + Tree expr1; + Tree tpe1; + switch (tpe) { + case Ident(TypeNames.WILDCARD_STAR): + expr1 = transform( + expr, mode & baseModes, definitions.seqType(pt)); + Type[] elemtps = expr1.type.baseType(definitions.SEQ_CLASS). + typeArgs(); + Type elemtp = (elemtps.length == 1) ? elemtps[0] + : Type.ErrorType; + tpe1 = tpe.setType(elemtp); + break; + default: + tpe1 = transform(tpe, TYPEmode); + expr1 = transform(expr, mode & baseModes, tpe1.type); + } return copy.Typed(tree, expr1, tpe1).setType(tpe1.type); case Function(Tree.ValDef[] vparams, Tree body): @@ -2166,7 +2186,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Symbol tsym = TreeInfo.methSymbol(fn1); if (tsym.kind != ERROR) { assert tsym.isType() : tsym; - switch (fn1.type.unalias()) { + switch (fn1.type.withDefaultArgs().unalias()) { case TypeRef(Type pre, Symbol c, Type[] argtypes): if (c.kind != CLASS) { error(tree.pos, @@ -2199,7 +2219,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { fn1.type = Type.PolyType( tsym.typeParams(), fn1.type); } - //System.out.println(TreeInfo.methSymbol(fn1) + ":" + tp + " --> " + fn1.type + " of " + fn1);//DEBUG + //System.out.println(TreeInfo.methSymbol(fn1) + " --> " + fn1.type + " of " + fn1);//DEBUG selfcc = TreeInfo.isSelfConstrCall(fn0); } break; diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java index 9c493db761..5178c3b703 100644 --- a/sources/scalac/typechecker/RefCheck.java +++ b/sources/scalac/typechecker/RefCheck.java @@ -105,30 +105,34 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { if ((other.flags & PRIVATE) == 0) { Symbol member1 = clazz.info().lookup(other.name); if (member1.kind != NONE && member1.owner() != other.owner()) { - Type self = clazz.thisType(); - Type otherinfo = normalizedInfo(self, other); - Type template = resultToAny(otherinfo); - switch (member1.info()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) { - if (normalizedInfo(self, alts[i]).isSubType(template)) { - 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()); + if (member1.kind == VAL) { + Type self = clazz.thisType(); + Type otherinfo = normalizedInfo(self, other); + Type template = resultToAny(otherinfo); + switch (member1.info()) { + case OverloadedType(Symbol[] alts, _): + for (int i = 0; i < alts.length; i++) { + if (normalizedInfo(self, alts[i]).isSubType(template)) { + 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: + if (normalizedInfo(self, member1).isSubType(template)) { + member = member1; } } - break; - default: - if (normalizedInfo(self, member1).isSubType(template)) { - member = member1; - } + } else { + member = member1; } } if (member != other) { @@ -209,14 +213,27 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { "\n an overriding definition in the current template is required"); } else { Type self = clazz.thisType(); + switch (other.kind) { case CLASS: overrideError(pos, member, other, "cannot override a class"); break; case ALIAS: + if (member.typeParams().length != 0) + overrideError(pos, member, other, "may not be parameterized"); + 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); 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); + if (!self.memberLoBound(other).isSubType(self.memberLoBound(member))) + overrideTypeError(pos, member, other, self, true); + break; default: if (other.isConstructor()) overrideError(pos, member, other, @@ -224,11 +241,6 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { if (!normalizedInfo(self, member).isSubType( normalizedInfo(self, other))) overrideTypeError(pos, member, other, self, false); - if (member.kind == TYPE && - !self.memberLoBound(other).isSubType( - self.memberLoBound(member))) - overrideTypeError(pos, member, other, self, true); - } } } @@ -911,7 +923,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { return super.transform(tree); case AliasTypeDef(_, _, _, _): - validateVariance(sym, sym.info(), NoVariance); + validateVariance(sym, sym.info(), CoVariance); return super.transform(tree); case Template(Tree[] bases, Tree[] body): @@ -942,11 +954,11 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { return super.transform(tree); case Apply(Tree fn, Tree[] args): + // convert case methods to new's Symbol fsym = TreeInfo.methSymbol(fn); assert fsym != Symbol.NONE : tree; if (fsym != null && fsym.isMethod() && !fsym.isConstructor() && (fsym.flags & CASE) != 0) { - // convert case methods to new's Symbol constr = fsym.type().resultType().symbol().primaryConstructor(); tree = gen.New(toConstructor(tree, constr)); } @@ -965,13 +977,16 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { return elimTypeNode(super.transform(tree)); case Ident(Name name): + if (name == TypeNames.WILDCARD_STAR) + return tree; + if( TreeInfo.isWildcardPattern( tree ) ) return elimTypeNode(tree); //System.out.println("name: "+name); Scope.Entry e = scopes[level].lookupEntry(name); //System.out.println("sym: "+sym); - if (sym != null && sym.isLocal() && sym == e.sym) { + if (sym.isLocal() && sym == e.sym) { int i = level; while (scopes[i] != e.owner) i--; int symindex = ((Integer) symIndex.get(tree.symbol())).intValue(); diff --git a/sources/scalac/util/Names.java b/sources/scalac/util/Names.java index 4a87801f23..03ce8048f9 100644 --- a/sources/scalac/util/Names.java +++ b/sources/scalac/util/Names.java @@ -51,6 +51,7 @@ public class Names { public static final Name COMPOUND_NAME = Name.fromString("<ct>"); public static final Name ANON_CLASS_NAME = Name.fromString("$anon"); public static final Name ZERO = Name.fromString("<zero>"); + public static final Name STAR = Name.fromString("*"); public static final Name CONSTRUCTOR = Name.fromString("<init>"); diff --git a/sources/scalac/util/TypeNames.java b/sources/scalac/util/TypeNames.java index cff4df05d4..9f7fea1144 100644 --- a/sources/scalac/util/TypeNames.java +++ b/sources/scalac/util/TypeNames.java @@ -11,5 +11,6 @@ package scalac.util; public class TypeNames { public static final Name EMPTY = Names.EMPTY.toTypeName(); + public static final Name WILDCARD_STAR = Name.fromString("_*").toTypeName(); } diff --git a/test/files/neg/S6.check b/test/files/neg/S6.check index 0647138103..6303e4c8e2 100644 --- a/test/files/neg/S6.check +++ b/test/files/neg/S6.check @@ -1,4 +1,4 @@ -S6.scala:11: cyclic aliasing or subtyping involving type S +S6.scala:11: illegal cyclic reference involving type S type S <: T; ^ one error found diff --git a/test/files/neg/S7.check b/test/files/neg/S7.check index c12c624cd7..59c57786b3 100644 --- a/test/files/neg/S7.check +++ b/test/files/neg/S7.check @@ -1,4 +1,4 @@ S7.scala:6: illegal cyclic reference involving class S7.A class C() extends a.A() {} - ^ + ^ one error found diff --git a/test/files/neg/bug128_129.check b/test/files/neg/bug128_129.check index d410b57095..79b20ec4a5 100644 --- a/test/files/neg/bug128_129.check +++ b/test/files/neg/bug128_129.check @@ -1,7 +1,10 @@ -bug128_129.scala:3: variable not allowed under alternative +bug128_129.scala:3: '=' expected but identifier found. val x | 1 = 2; // not allowed - ^ + ^ +bug128_129.scala:3: illegal start of expression + val x | 1 = 2; // not allowed + ^ bug128_129.scala:10: recursive patterns not allowed case PT(a@PT(a)) => // not allowed ^ -two errors found +three errors found diff --git a/test/files/neg/bug96.check b/test/files/neg/bug96.check index ab5871b39e..1ceaa84a94 100644 --- a/test/files/neg/bug96.check +++ b/test/files/neg/bug96.check @@ -1,5 +1,4 @@ -bug96.scala:5: method foo in class B of type (def scala.Any)scala.Object - cannot override method foo in class A of type (scala.Any)scala.Object +bug96.scala:5: method foo overrides nothing override def foo(def x: Any): Object = null; ^ one error found diff --git a/test/files/neg/matthias2.check b/test/files/neg/matthias2.check index 052be577b5..b9a6d799f9 100644 --- a/test/files/neg/matthias2.check +++ b/test/files/neg/matthias2.check @@ -1,4 +1,4 @@ -matthias2.scala:7: cyclic aliasing or subtyping involving value y +matthias2.scala:7: illegal cyclic reference involving value y override val y: T; - ^ + ^ one error found diff --git a/test/neg/S6.check b/test/neg/S6.check index 0647138103..6303e4c8e2 100644 --- a/test/neg/S6.check +++ b/test/neg/S6.check @@ -1,4 +1,4 @@ -S6.scala:11: cyclic aliasing or subtyping involving type S +S6.scala:11: illegal cyclic reference involving type S type S <: T; ^ one error found diff --git a/test/neg/S7.check b/test/neg/S7.check index c12c624cd7..59c57786b3 100644 --- a/test/neg/S7.check +++ b/test/neg/S7.check @@ -1,4 +1,4 @@ S7.scala:6: illegal cyclic reference involving class S7.A class C() extends a.A() {} - ^ + ^ one error found diff --git a/test/neg/bug128_129.check b/test/neg/bug128_129.check index d410b57095..79b20ec4a5 100644 --- a/test/neg/bug128_129.check +++ b/test/neg/bug128_129.check @@ -1,7 +1,10 @@ -bug128_129.scala:3: variable not allowed under alternative +bug128_129.scala:3: '=' expected but identifier found. val x | 1 = 2; // not allowed - ^ + ^ +bug128_129.scala:3: illegal start of expression + val x | 1 = 2; // not allowed + ^ bug128_129.scala:10: recursive patterns not allowed case PT(a@PT(a)) => // not allowed ^ -two errors found +three errors found diff --git a/test/neg/bug96.check b/test/neg/bug96.check index ab5871b39e..1ceaa84a94 100644 --- a/test/neg/bug96.check +++ b/test/neg/bug96.check @@ -1,5 +1,4 @@ -bug96.scala:5: method foo in class B of type (def scala.Any)scala.Object - cannot override method foo in class A of type (scala.Any)scala.Object +bug96.scala:5: method foo overrides nothing override def foo(def x: Any): Object = null; ^ one error found diff --git a/test/neg/matthias2.check b/test/neg/matthias2.check index 052be577b5..b9a6d799f9 100644 --- a/test/neg/matthias2.check +++ b/test/neg/matthias2.check @@ -1,4 +1,4 @@ -matthias2.scala:7: cyclic aliasing or subtyping involving value y +matthias2.scala:7: illegal cyclic reference involving value y override val y: T; - ^ + ^ one error found |