summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-09-18 10:00:06 +0000
committerMartin Odersky <odersky@gmail.com>2003-09-18 10:00:06 +0000
commitc0de8fd882c937b7d05368ce0dd5548edea7f839 (patch)
tree5c744cef4bb771689c8e81c896b337bd43199fa9
parent5b9b5356411cbd5e4de94d6c84832f99cd10b5de (diff)
downloadscala-c0de8fd882c937b7d05368ce0dd5548edea7f839.tar.gz
scala-c0de8fd882c937b7d05368ce0dd5548edea7f839.tar.bz2
scala-c0de8fd882c937b7d05368ce0dd5548edea7f839.zip
*** empty log message ***
-rw-r--r--sources/scala/List.scala2
-rw-r--r--sources/scala/Predef.scala4
-rw-r--r--sources/scalac/ast/parser/Parser.java26
-rw-r--r--sources/scalac/symtab/Definitions.java2
-rw-r--r--sources/scalac/symtab/Type.java104
-rw-r--r--sources/scalac/symtab/classfile/UnPickle.java13
-rw-r--r--sources/scalac/transformer/UnCurry.java72
-rw-r--r--sources/scalac/typechecker/Analyzer.java48
-rw-r--r--sources/scalac/typechecker/RefCheck.java75
-rw-r--r--sources/scalac/util/Names.java1
-rw-r--r--sources/scalac/util/TypeNames.java1
-rw-r--r--test/files/neg/S6.check2
-rw-r--r--test/files/neg/S7.check2
-rw-r--r--test/files/neg/bug128_129.check9
-rw-r--r--test/files/neg/bug96.check3
-rw-r--r--test/files/neg/matthias2.check4
-rw-r--r--test/neg/S6.check2
-rw-r--r--test/neg/S7.check2
-rw-r--r--test/neg/bug128_129.check9
-rw-r--r--test/neg/bug96.check3
-rw-r--r--test/neg/matthias2.check4
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