summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-03-06 19:14:59 +0000
committerMartin Odersky <odersky@gmail.com>2003-03-06 19:14:59 +0000
commita16dd265fddd7da26564109f4026fb1d12c1071a (patch)
tree702ba02d30d68d21d51ac5c83f31b448cd654ce1 /sources
parentbcc3899778ce607df11b471a641493037a8c962f (diff)
downloadscala-a16dd265fddd7da26564109f4026fb1d12c1071a.tar.gz
scala-a16dd265fddd7da26564109f4026fb1d12c1071a.tar.bz2
scala-a16dd265fddd7da26564109f4026fb1d12c1071a.zip
*** empty log message ***
Diffstat (limited to 'sources')
-rw-r--r--sources/scalac/symtab/Type.java57
-rw-r--r--sources/scalac/transformer/LambdaLift.java37
-rw-r--r--sources/scalac/transformer/UnCurry.java4
-rw-r--r--sources/scalac/typechecker/Analyzer.java318
-rw-r--r--sources/scalac/util/Names.java1
5 files changed, 254 insertions, 163 deletions
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index a11f8bea8f..0f5a7ac6d4 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -80,7 +80,11 @@ public class Type implements Modifiers, Kinds, TypeTags {
public static final Type[] NO_ARRAY = new Type[0];
public static SingleType singleType(Type pre, Symbol sym) {
- return new ExtSingleType(pre, sym);
+ if (pre.isStable() || pre == ErrorType)
+ return new ExtSingleType(pre, sym);
+ else
+ throw new Type.Error(
+ "malformed type: " + pre + "." + sym.nameString() + ".type");
}
public static TypeRef appliedType(Type tycon, Type[] args) {
@@ -116,6 +120,16 @@ public class Type implements Modifiers, Kinds, TypeTags {
return res;
}
+ public static Type typeRef(Type pre, Symbol sym, Type[] args) {
+ if (pre.isStable() || 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());
+ }
+
static class ExtSingleType extends SingleType {
Type tp = null;
int definedId = -1;
@@ -569,12 +583,12 @@ public class Type implements Modifiers, Kinds, TypeTags {
case ThisType(_):
return tp;
case TypeRef(Type pre, Symbol sym, Type[] args):
- Type pre1 = map(pre);
+ Type pre1 = apply(pre);
Type[] args1 = map(args);
if (pre1 == pre && args1 == args) return tp;
else return TypeRef(pre1, sym, args1);
case SingleType(Type pre, Symbol sym):
- Type pre1 = map(pre);
+ Type pre1 = apply(pre);
if (pre1 == pre) return tp;
else return singleType(pre1, sym);
case CompoundType(Type[] parts, Scope members):
@@ -720,10 +734,11 @@ public class Type implements Modifiers, Kinds, TypeTags {
return pre.memberInfo(sym).baseType(clazz);
else if (clazz.isCompoundSym())
return NoType;
- else
+ else {
return sym.baseType(clazz)
.asSeenFrom(pre, clazz.owner())
.subst(sym.typeParams(), args);
+ }
case CompoundType(Type[] parts, _):
for (int i = parts.length - 1; i >= 0; i--) {
@@ -764,7 +779,15 @@ public class Type implements Modifiers, Kinds, TypeTags {
this.pre = pre; this.clazz = clazz;
}
+ public Type apply0(Type t) {
+ Type t1 = apply0(t);
+ System.out.println(t + " as seen from (" + pre + "," + clazz + ") = " + t1);//debug
+ return t1;
+ }
+
public Type apply(Type t) {
+ if (pre == NoType || clazz.kind != CLASS)
+ return t;
switch (t) {
case ThisType(Symbol sym):
return t.toPrefix(pre, clazz);
@@ -786,7 +809,8 @@ public class Type implements Modifiers, Kinds, TypeTags {
}
return t1;
} else {
- Type prefix1 = prefix.toPrefix(pre, clazz);
+ //Type prefix1 = prefix.toPrefix(pre, clazz);
+ Type prefix1 = apply(prefix);
Symbol sym1 = (prefix1 == prefix || (sym.flags & MODUL) != 0)
? sym : prefix1.rebind(sym);
boolean prevTypeArg = typeArg;
@@ -799,7 +823,8 @@ public class Type implements Modifiers, Kinds, TypeTags {
case SingleType(Type prefix, Symbol sym):
try {
- Type prefix1 = prefix.toPrefix(pre, clazz);
+ //Type prefix1 = prefix.toPrefix(pre, clazz);
+ Type prefix1 = apply(prefix);
if (prefix1 == prefix) return t;
else return singleType(prefix1, prefix1.rebind(sym));
} catch (Type.Error ex) {
@@ -849,17 +874,10 @@ public class Type implements Modifiers, Kinds, TypeTags {
Type toPrefix(Type pre, Symbol clazz) {
if (pre == NoType || clazz.kind != CLASS)
return this;
- if (symbol().isSubClass(clazz) &&
- pre.symbol().isSubClass(symbol())) {
- if (!pre.isStable() && pre != ErrorType) {
- throw new Type.Error (
- "malformed type: " + pre + "." + symbol().nameString());
- }
+ else if (symbol().isSubClass(clazz) && pre.symbol().isSubClass(symbol()))
return pre;
- } else {
- return toPrefix(
- pre.baseType(clazz).prefix(), clazz.owner());
- }
+ else
+ return toPrefix(pre.baseType(clazz).prefix(), clazz.owner());
}
/** This type Types as seen from prefix `pre' and class `clazz'. This means:
@@ -897,10 +915,9 @@ public class Type implements Modifiers, Kinds, TypeTags {
}
private Type memberTransform(Symbol sym, Type tp) {
- Type tp1 = tp.asSeenFrom(narrow(), sym.owner());
- Type tp2 = tp1.asSeenFrom(this, widen().symbol());
- //if (Global.instance.debug) System.out.println(this + "/" + widen() + ".memberType(" + sym + ":" + tp + ") = " + tp1 + "/" + tp2);//DEBUG
- return tp2;
+ Type tp1 = tp.asSeenFrom(this, sym.owner());
+ //if (Global.instance.debug) System.out.println(this + ".memberType(" + sym + ":" + tp + ") = " + tp1);//debug
+ return tp1;
}
// Substitutions ---------------------------------------------------------------
diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java
index 608db61eae..48f1edf66a 100644
--- a/sources/scalac/transformer/LambdaLift.java
+++ b/sources/scalac/transformer/LambdaLift.java
@@ -380,6 +380,11 @@ public class LambdaLift extends OwnerTransformer
}
return copy.ValDef(tree, mods, name1, tpe1, rhs1);
+ case Tuple(Tree[] args):
+ Tree tree1 = mkList(tree.pos, tree.type, transform(args));
+ //new scalac.ast.printer.TextTreePrinter().print("TUPLE: ").print(tree).print("\n ==> \n").print(tree1).println().end();//DEBUG
+ return tree1;
+
case Apply(Tree fn, Tree[] args):
Symbol fsym = TreeInfo.methSymbol(fn);
Tree fn1 = transform(fn);
@@ -535,4 +540,36 @@ public class LambdaLift extends OwnerTransformer
return args;
}
}
+
+ Tree mkList(int pos, Type tpe, Tree[] args) {
+ return mkList(pos, tpe.typeArgs()[0], args, 0);
+ }
+
+ Tree mkList(int pos, Type elemtpe, Tree[] args, int start) {
+ if (start == args.length) return mkNil(pos, elemtpe);
+ else return mkCons(pos, elemtpe, args[start],
+ mkList(pos, elemtpe, args, start + 1));
+ }
+
+ Tree mkNil(int pos, Type elemtpe) {
+ return gen.New(
+ gen.Apply(
+ gen.TypeApply(
+ gen.mkRef(
+ pos,
+ global.definitions.getClass(Names.scala_Nil).constructor()),
+ new Tree[]{gen.mkType(pos, elemtpe)}),
+ new Tree[]{}));
+ }
+
+ Tree mkCons(int pos, Type elemtpe, Tree hd, Tree tl) {
+ return gen.New(
+ gen.Apply(
+ gen.TypeApply(
+ gen.mkRef(
+ pos,
+ global.definitions.getClass(Names.scala_COLONCOLON).constructor()),
+ new Tree[]{gen.mkType(pos, elemtpe)}),
+ new Tree[]{hd, tl}));
+ }
}
diff --git a/sources/scalac/transformer/UnCurry.java b/sources/scalac/transformer/UnCurry.java
index 9647b43852..427c7a0efd 100644
--- a/sources/scalac/transformer/UnCurry.java
+++ b/sources/scalac/transformer/UnCurry.java
@@ -146,10 +146,10 @@ public class UnCurry extends OwnerTransformer
private Tree[] transformArgs(int pos, Tree[] args, Type methtype) {
switch (methtype) {
case MethodType(Symbol[] params, _):
+ Tree[] args0 = args;//debug
if (params.length == 1 && (params[0].flags & REPEATED) != 0) {
assert (args.length != 1 || !(args[0] instanceof Tree.Tuple));
- args = new Tree[]{
- make.Tuple(pos, args).setType(params[0].type())};
+ args = new Tree[]{make.Tuple(pos, args).setType(params[0].type())};
}
Tree[] args1 = args;
for (int i = 0; i < args.length; i++) {
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index 1a37745586..fe6a0b13d5 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -182,6 +182,24 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
error(pos, infer.typeErrorMsg("type mismatch", found, req) + explanation);
}
+ void reportTypeError(int pos, Type.Error ex) {
+ if (ex instanceof CyclicReference) {
+ if (global.debug) ex.printStackTrace();//DEBUG
+ CyclicReference cyc = (CyclicReference) ex;
+ if (cyc.info instanceof LazyTreeType) {
+ switch (((LazyTreeType) cyc.info).tree) {
+ case ValDef(_, _, _, _):
+ error(pos, "recursive " + cyc.sym + " needs type");
+ break;
+ case DefDef(_, _, _, _, _, _):
+ error(pos, "recursive function " + cyc.sym.name + " needs result type");
+ }
+ }
+ }
+ //throw ex;//DEBUG
+ error(pos, ex.msg);
+ }
+
// Name resolution -----------------------------------------------------------
String decode(Name name) {
@@ -281,6 +299,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
* nested within definition of base class, or that occur within same
* statement sequence.
* - self-type of current class is a subtype of self-type of each parent class.
+ * - parent types do not refer to value parameters of class.
*/
void validateParentClasses(Tree[] constrs, Type[] parents, Type selfType) {
if (parents.length == 0 || !checkClassType(constrs[0].pos, parents[0])) return;
@@ -434,7 +453,28 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
}
- /** Check that
+ /** Check that type `tp' is not a subtype of itself.
+ */
+ public void checkNonCyclic(int pos, Type tp) {
+ switch (tp) {
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ sym.initialize();
+ if ((sym.flags & LOCKED) != 0) {
+ error(pos, "cyclic aliasing or subtyping involving " + sym);
+ } else if (sym.kind == ALIAS || sym.kind == TYPE) {
+ assert (sym.flags & LOCKED) == 0;
+ sym.flags |= LOCKED;
+ checkNonCyclic(
+ pos, pre.memberInfo(sym).subst(sym.typeParams(), args));
+ sym.flags &= ~LOCKED;
+ }
+ break;
+ case CompoundType(Type[] parents, Scope members):
+ for (int i = 0; i < parents.length; i++) {
+ checkNonCyclic(pos, parents[i]);
+ }
+ }
+ }
/** Check that type does not refer to components defined in current scope.
*/
@@ -451,25 +491,23 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
public Type apply(Type t) {
switch (t.unalias()) {
case TypeRef(ThisType(_), Symbol sym, Type[] args):
- Scope.Entry e = context.scope.lookupEntry(sym.name);
- if (e.sym == sym && e.owner == context.scope) {
- throw new Type.Error(
- "type " + t + " escapes its defining scope");
- } else {
- map(args);
- return t;
- }
+ checkNoEscape(t, sym);
+ break;
case SingleType(ThisType(_), Symbol sym):
- Scope.Entry e = context.scope.lookupEntry(sym.name);
- if (e.sym == sym && e.owner == context.scope) {
- return apply(t.widen());
- } else {
- return t;
- }
- default:
- return map(t);
+ checkNoEscape(t, sym);
+ break;
+ }
+ return map(t);
+ }
+ private void checkNoEscape(Type t, Symbol sym) {
+ Scope.Entry e = context.scope.lookupEntry(sym.name);
+ if (e.sym == sym && e.owner == context.scope &&
+ !(e.sym.kind == TYPE && (e.sym.flags & PARAM) != 0)) {
+ throw new Type.Error(
+ "type " + t + " escapes its defining scope");
}
- }};
+ }
+ };
/** Check that tree represents a pure definition.
*/
@@ -755,122 +793,129 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Type savedPt = this.pt;
this.pt = Type.AnyType;
- Symbol sym = tree.symbol();
- if (global.debug) System.out.println("defining " + sym);//debug
- Type owntype;
- switch (tree) {
- case ClassDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ):
- assert (mods & LOCKED) == 0 || sym.isAnonymousClass(): sym; // to catch repeated evaluations
- ((ClassDef) tree).mods |= LOCKED;
-
- pushContext(tree, sym.constructor(), new Scope(context.scope));
- Symbol[] tparamSyms = enterParams(tparams);
- Symbol[][] vparamSyms = enterParams(vparams);
-
- if ((mods & CASE) != 0 && vparams.length > 0)
- templ.body = desugarize.addCaseElements(templ.body, vparams[0]);
-
- for (int i = 0; i < vparamSyms.length; i++)
- for (int j = 0; j < vparamSyms[i].length; j++)
- context.scope.unlink(
- context.scope.lookupEntry(vparamSyms[i][j].name));
- Type constrtype = makeMethodType(
- tparamSyms,
- vparamSyms,
- Type.TypeRef(sym.owner().thisType(), sym, Symbol.type(tparamSyms)));
- sym.constructor().setInfo(constrtype);
- // necessary so that we can access tparams
- sym.constructor().flags |= INITIALIZED;
- if (tpe != Tree.Empty)
- sym.setTypeOfThis(transform(tpe, TYPEmode).type);
-
- reenterParams(vparams);
- defineTemplate(templ, sym);
- owntype = templ.type;
- popContext();
- break;
+ try {
+ Symbol sym = tree.symbol();
+ if (global.debug) System.out.println("defining " + sym);//debug
+ Type owntype;
+ switch (tree) {
+ case ClassDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ):
+ if ((mods & LOCKED) != 0 && !sym.isAnonymousClass()) {
+ sym.setInfo(Type.ErrorType);
+ throw new CyclicReference(sym, Type.NoType);
+ }
- case ModuleDef(int mods, Name name, Tree tpe, Tree.Template templ):
- Symbol clazz = sym.moduleClass();
- defineTemplate(templ, clazz);
- clazz.setInfo(templ.type);
- if (tpe == Tree.Empty) owntype = clazz.type();
- else owntype = transform(tpe, TYPEmode).type;
- break;
+ ((ClassDef) tree).mods |= LOCKED;
- case ValDef(int mods, Name name, Tree tpe, Tree rhs):
- if (tpe == Tree.Empty) {
- pushContext(tree, sym, context.scope);
- if (rhs == Tree.Empty) {
- if ((sym.owner().flags & ACCESSOR) != 0) {
- // this is the paremeter of a variable setter method.
- ((ValDef) tree).tpe = tpe =
- gen.mkType(tree.pos, sym.owner().accessed().type());
- } else {
- error(tree.pos, "missing parameter type");
- ((ValDef) tree).tpe = tpe =
- gen.mkType(tree.pos, Type.ErrorType);
- }
- owntype = tpe.type;
- } else {
- if ((mods & CASE) != 0) {
- //rhs was already attributed
+ pushContext(tree, sym.constructor(), new Scope(context.scope));
+ Symbol[] tparamSyms = enterParams(tparams);
+ Symbol[][] vparamSyms = enterParams(vparams);
+
+ if ((mods & CASE) != 0 && vparams.length > 0)
+ templ.body = desugarize.addCaseElements(templ.body, vparams[0]);
+
+ Type constrtype = makeMethodType(
+ tparamSyms,
+ vparamSyms,
+ Type.TypeRef(sym.owner().thisType(), sym, Symbol.type(tparamSyms)));
+ sym.constructor().setInfo(constrtype);
+ // necessary so that we can access tparams
+ sym.constructor().flags |= INITIALIZED;
+
+ if (tpe != Tree.Empty)
+ sym.setTypeOfThis(
+ checkNoEscape(tpe.pos, transform(tpe, TYPEmode).type));
+
+ defineTemplate(templ, sym);
+ owntype = templ.type;
+ popContext();
+ break;
+
+ case ModuleDef(int mods, Name name, Tree tpe, Tree.Template templ):
+ Symbol clazz = sym.moduleClass();
+ defineTemplate(templ, clazz);
+ clazz.setInfo(templ.type);
+ if (tpe == Tree.Empty) owntype = clazz.type();
+ else owntype = transform(tpe, TYPEmode).type;
+ break;
+
+ case ValDef(int mods, Name name, Tree tpe, Tree rhs):
+ if (tpe == Tree.Empty) {
+ pushContext(tree, sym, context.scope);
+ if (rhs == Tree.Empty) {
+ if ((sym.owner().flags & ACCESSOR) != 0) {
+ // this is the paremeter of a variable setter method.
+ ((ValDef) tree).tpe = tpe =
+ gen.mkType(tree.pos, sym.owner().accessed().type());
+ } else {
+ error(tree.pos, "missing parameter type");
+ ((ValDef) tree).tpe = tpe =
+ gen.mkType(tree.pos, Type.ErrorType);
+ }
+ owntype = tpe.type;
} else {
- ((ValDef) tree).rhs = rhs = transform(rhs, EXPRmode);
+ if ((mods & CASE) != 0) {
+ //rhs was already attributed
+ } else {
+ ((ValDef) tree).rhs = rhs = transform(rhs, EXPRmode);
+ }
+ owntype = rhs.type;
}
- owntype = rhs.type;
+ popContext();
+ } else {
+ owntype = transform(tpe, TYPEmode).type;
}
- popContext();
- } else {
- owntype = transform(tpe, TYPEmode).type;
- }
- break;
-
- case DefDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs):
- pushContext(tree, sym, new Scope(context.scope));
- Symbol[] tparamSyms = enterParams(tparams);
- Type restpe = null;
- if (tpe != Tree.Empty) {
- restpe = transform(tpe, TYPEmode).type;
- }
- Symbol[][] vparamSyms = enterParams(vparams);
- if (tpe == Tree.Empty) {
- int rhsmode = name.isConstrName() ? CONSTRmode : EXPRmode;
- ((DefDef) tree).rhs = rhs = transform(rhs, rhsmode);
- restpe = rhs.type;
- }
- popContext();
- owntype = makeMethodType(tparamSyms, vparamSyms, restpe);
- break;
+ break;
- case TypeDef(int mods, Name name, Tree rhs):
- //todo: alwyas have context.owner as owner.
- if (sym.kind == TYPE) {
- pushContext(rhs, context.owner, context.scope);
- context.delayArgs = true;
- owntype = transform(rhs, TYPEmode).type;
- owntype.symbol().initialize();//to detect cycles
- popContext();
- } else { // sym.kind == ALIAS
+ case DefDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs):
pushContext(tree, sym, new Scope(context.scope));
- owntype = transform(rhs, TYPEmode | FUNmode).type;
+ Symbol[] tparamSyms = enterParams(tparams);
+ Symbol[][] vparamSyms = enterParams(vparams);
+ Type restpe;
+ if (tpe == Tree.Empty) {
+ int rhsmode = name.isConstrName() ? CONSTRmode : EXPRmode;
+ ((DefDef) tree).rhs = rhs = transform(rhs, rhsmode);
+ restpe = checkNoEscape(rhs.pos, rhs.type);
+ } else {
+ restpe = checkNoEscape(
+ tpe.pos, transform(tpe, TYPEmode).type);
+ }
popContext();
- }
- break;
+ owntype = makeMethodType(tparamSyms, vparamSyms, restpe);
+ break;
- case Import(Tree expr, Name[] selectors):
- Tree expr1 = transform(expr, EXPRmode | QUALmode);
- ((Import) tree).expr = expr1;
- checkStable(expr1);
- owntype = expr1.type;
- break;
+ case TypeDef(int mods, Name name, Tree rhs):
+ //todo: alwyas have context.owner as owner.
+ if (sym.kind == TYPE) {
+ pushContext(rhs, context.owner, context.scope);
+ context.delayArgs = true;
+ owntype = transform(rhs, TYPEmode).type;
+ owntype.symbol().initialize();//to detect cycles
+ popContext();
+ } else { // sym.kind == ALIAS
+ pushContext(tree, sym, new Scope(context.scope));
+ owntype = transform(rhs, TYPEmode | FUNmode).type;
+ popContext();
+ }
+ checkNonCyclic(tree.pos, owntype);
+ break;
- default:
- throw new ApplicationError();
+ case Import(Tree expr, Name[] selectors):
+ Tree expr1 = transform(expr, EXPRmode | QUALmode);
+ ((Import) tree).expr = expr1;
+ checkStable(expr1);
+ owntype = expr1.type;
+ break;
+
+ default:
+ throw new ApplicationError();
+ }
+ sym.setInfo(owntype);
+ validate(sym);
+ if (global.debug) System.out.println("defined " + sym);//debug
+ } catch (Type.Error ex) {
+ reportTypeError(tree.pos, ex);
}
- sym.setInfo(owntype);
- validate(sym);
- if (global.debug) System.out.println("defined " + sym);//debug
+
this.unit = savedUnit;
this.context = savedContext;
this.mode = savedMode;
@@ -1167,8 +1212,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
pushContext(constrs[i], context.owner, context.scope);
context.delayArgs = delayArgs;
constrs[i] = transform(constrs[i], CONSTRmode, pt);
- if (constrs[i].hasSymbol())
- constrs[i].symbol().initialize();//to detect cycles
+ Symbol c = TreeInfo.methSymbol(constrs[i]).primaryConstructorClass();
+ if (c.kind == CLASS) c.initialize();//to detect cycles
popContext();
}
return constrs;
@@ -1590,10 +1635,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
pushContext(tree, sym.constructor(), new Scope(context.scope));
reenterParams(tparams);
Tree.TypeDef[] tparams1 = transform(tparams);
- Tree tpe1 = transform(tpe);
reenterParams(vparams);
Tree.ValDef[][] vparams1 = transform(vparams);
+ Tree tpe1 = transform(tpe);
Tree.Template templ1 = transformTemplate(templ, sym);
+ for (int i = 0; i < templ1.parents.length; i++)
+ checkNoEscape(templ1.parents[i].pos, templ1.parents[i].type);
+
if ((sym.flags & ABSTRACTCLASS) == 0 &&
!sym.type().isSubType(sym.typeOfThis()))
error(sym.pos, sym +
@@ -1631,9 +1679,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
pushContext(tree, sym, new Scope(context.scope));
reenterParams(tparams);
Tree.TypeDef[] tparams1 = transform(tparams);
- Tree tpe1 = transform(tpe, TYPEmode);
reenterParams(vparams);
Tree.ValDef[][] vparams1 = transform(vparams);
+ Tree tpe1 = transform(tpe, TYPEmode);
Tree rhs1 = rhs;
if (tpe1 == Tree.Empty) {
tpe1 = gen.mkType(rhs1.pos, rhs1.type);
@@ -2018,20 +2066,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
throw new ApplicationError("illegal tree: " + tree);
}
} catch (Type.Error ex) {
- if (ex instanceof CyclicReference) {
- if (global.debug) ex.printStackTrace();//DEBUG
- CyclicReference cyc = (CyclicReference) ex;
- if (cyc.info instanceof LazyTreeType) {
- switch (((LazyTreeType) cyc.info).tree) {
- case ValDef(_, _, _, _):
- return error(tree, "recursive " + cyc.sym + " needs type");
- case DefDef(_, _, _, _, _, _):
- return error(tree, "recursive function " + cyc.sym.name + " needs result type");
- }
- }
- }
- throw ex;//debug
- //return error(tree, ex.msg);
+ reportTypeError(tree.pos, ex);
+ return tree;
}
}
diff --git a/sources/scalac/util/Names.java b/sources/scalac/util/Names.java
index c54f044f06..a70d6beedb 100644
--- a/sources/scalac/util/Names.java
+++ b/sources/scalac/util/Names.java
@@ -75,6 +75,7 @@ public class Names {
public static final Name predef = Name.fromString("predef");
public static final Name runtime = Name.fromString("runtime");
public static final Name scala = Name.fromString("scala");
+ public static final Name scala_COLONCOLON = Name.fromString("scala." + COLONCOLON);
public static final Name scala_Algebraic = Name.fromString("scala.Algebraic");
public static final Name scala_Any = Name.fromString("scala.Any");
public static final Name scala_AnyRef = Name.fromString("scala.AnyRef");