summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-10-16 07:19:23 +0000
committerMartin Odersky <odersky@gmail.com>2005-10-16 07:19:23 +0000
commitb10fe9805e2e1c9543c6ce7df7779dbcb1d90a3f (patch)
tree16d8e6ac9db5019408bb5e97fb748c3c5f714da8
parentb8818bf2920c8cc32c17b8dfc20ee57823b2ec79 (diff)
downloadscala-b10fe9805e2e1c9543c6ce7df7779dbcb1d90a3f.tar.gz
scala-b10fe9805e2e1c9543c6ce7df7779dbcb1d90a3f.tar.bz2
scala-b10fe9805e2e1c9543c6ce7df7779dbcb1d90a3f.zip
*** empty log message ***
-rwxr-xr-xsources/scala/tools/nsc/ast/parser/Parsers.scala5
-rwxr-xr-xsources/scala/tools/nsc/symtab/Constants.scala2
-rwxr-xr-xsources/scala/tools/nsc/symtab/Definitions.scala9
-rwxr-xr-xsources/scala/tools/nsc/symtab/Names.scala2
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala8
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala44
-rwxr-xr-xsources/scala/tools/nsc/transform/Erasure.scala28
-rwxr-xr-xsources/scala/tools/nsc/transform/Mixin.scala3
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Infer.scala12
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Namers.scala3
-rwxr-xr-xsources/scala/tools/nsc/typechecker/RefChecks.scala3
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala87
12 files changed, 142 insertions, 64 deletions
diff --git a/sources/scala/tools/nsc/ast/parser/Parsers.scala b/sources/scala/tools/nsc/ast/parser/Parsers.scala
index d8a4f9e49d..d2155f5e39 100755
--- a/sources/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/sources/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1149,7 +1149,10 @@ import Tokens._;
if (owner == nme.CONSTRUCTOR &&
(result.isEmpty || (!result.head.isEmpty &&
(result.head.head.mods & Flags.IMPLICIT) != 0)))
- syntaxError(pos, "auxiliary constructor needs non-implicit parameter list", false);
+ if (in.token == LBRACKET)
+ syntaxError(pos, "no type parameters allowed here", false);
+ else
+ syntaxError(pos, "auxiliary constructor needs non-implicit parameter list", false);
addImplicitViews(owner, result, implicitViews)
}
diff --git a/sources/scala/tools/nsc/symtab/Constants.scala b/sources/scala/tools/nsc/symtab/Constants.scala
index 165ff705d4..a2dd8d749a 100755
--- a/sources/scala/tools/nsc/symtab/Constants.scala
+++ b/sources/scala/tools/nsc/symtab/Constants.scala
@@ -176,7 +176,7 @@ import classfile.PickleFormat._;
}
def stringValue: String =
- if (value == null) "<null>" else value.toString();
+ if (value == null) "null" else value.toString();
override def hashCode(): int =
if (value == null) 0 else value.hashCode() * 41 + 17;
diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala
index 5397c7d5fc..7063f47987 100755
--- a/sources/scala/tools/nsc/symtab/Definitions.scala
+++ b/sources/scala/tools/nsc/symtab/Definitions.scala
@@ -292,13 +292,16 @@ import Flags._;
ScalaPackageClass = ScalaPackage.tpe.symbol;
AnyClass = newClass(ScalaPackageClass, "Any", List());
- AnyValClass = getClass("scala.AnyVal");
+ AnyValClass = getClass("scala.AnyVal") setFlag SEALED;
ObjectClass = getClass("java.lang.Object");
AnyRefClass = newAlias(ScalaPackageClass, "AnyRef", ObjectClass.typeConstructor);
- AllRefClass = newClass(ScalaPackageClass, "AllRef", List(AnyRefClass.typeConstructor));
- AllClass = newClass(ScalaPackageClass, "All", List(AnyClass.typeConstructor));
+ AllRefClass = newClass(ScalaPackageClass, "AllRef", List(AnyRefClass.typeConstructor))
+ setFlag (ABSTRACT | TRAIT | FINAL);
+
+ AllClass = newClass(ScalaPackageClass, "All", List(AnyClass.typeConstructor))
+ setFlag (ABSTRACT | TRAIT | FINAL);
StringClass = getClass("java.lang.String");
ThrowableClass = getClass("java.lang.Throwable");
diff --git a/sources/scala/tools/nsc/symtab/Names.scala b/sources/scala/tools/nsc/symtab/Names.scala
index 3c15ad920f..5e82e1178e 100755
--- a/sources/scala/tools/nsc/symtab/Names.scala
+++ b/sources/scala/tools/nsc/symtab/Names.scala
@@ -16,7 +16,7 @@ class Names {
private val HASH_MASK = 0x7FFF;
private val NAME_SIZE = 0x20000;
- final val nameDebug = true;
+ final val nameDebug = false;
/** memory to store all names sequentially
*/
diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala
index 2fef116ccd..44b02bc51c 100755
--- a/sources/scala/tools/nsc/symtab/Symbols.scala
+++ b/sources/scala/tools/nsc/symtab/Symbols.scala
@@ -684,7 +684,7 @@ import Flags._;
* e.g., "class Foo", "method Bar".
*/
override def toString(): String =
- compose(List(kindString, nameString));
+ compose(List(kindString, if (isClassConstructor) owner.nameString else nameString));
/** String representation of location. */
final def locationString: String =
@@ -814,14 +814,14 @@ import Flags._;
private var tpeCache: Type = _;
private var tpePhase: Phase = null;
override def tpe: Type = {
- assert(tpeCache ne NoType, this);
+ if (tpeCache eq NoType) throw CyclicReference(this, typeConstructor);
if (tpePhase != phase) {
if (isValid(tpePhase)) {
- tpePhase = phase
+ tpePhase = phase
} else {
if (isInitialized) tpePhase = phase;
tpeCache = NoType;
- val targs = if (phase.erasedTypes && this != ArrayClass) List()
+ val targs = if (phase.erasedTypes && this != ArrayClass) List()
else unsafeTypeParams map (.tpe);
tpeCache = typeRef(if (isTypeParameter) NoPrefix else owner.thisType, this, targs)
}
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index 3b1c8322c7..4ed2563d6c 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -147,18 +147,18 @@ import Flags._;
def members: List[Symbol] = findMember(nme.ANYNAME, 0, 0).alternatives;
/** A list of all non-private members of this type (defined or inherited) */
- def nonPrivateMembers: List[Symbol] = findMember(nme.ANYNAME, PRIVATE, 0).alternatives;
+ def nonPrivateMembers: List[Symbol] = findMember(nme.ANYNAME, PRIVATE | BRIDGE, 0).alternatives;
/** A list of all implicit symbols of this type (defined or inherited) */
- def implicitMembers: List[Symbol] = findMember(nme.ANYNAME, 0, IMPLICIT).alternatives;
+ def implicitMembers: List[Symbol] = findMember(nme.ANYNAME, BRIDGE, IMPLICIT).alternatives;
/** The member with given name,
* an OverloadedSymbol if several exist, NoSymbol if none exist */
- def member(name: Name): Symbol = findMember(name, 0, 0);
+ def member(name: Name): Symbol = findMember(name, BRIDGE, 0);
/** The non-private member with given name,
* an OverloadedSymbol if several exist, NoSymbol if none exist */
- def nonPrivateMember(name: Name): Symbol = findMember(name, PRIVATE, 0);
+ def nonPrivateMember(name: Name): Symbol = findMember(name, PRIVATE | BRIDGE, 0);
/** The least type instance of given class which is a supertype
* of this type */
@@ -567,19 +567,23 @@ import Flags._;
index(i) = 0;
i = i + 1
}
+ def nextBaseType(i: int): Type = {
+ val j = index(i);
+ val pci = pclosure(i);
+ if (j < pci.length) pci(j) else AnyClass.tpe
+ }
val limit = pclosure(0).length;
while (index(0) != limit) {
- var minSym: Symbol = pclosure(0)(index(0)).symbol;
+ var minSym: Symbol = nextBaseType(0).symbol;
i = 1;
while (i < nparents) {
- if (pclosure(i)(index(i)).symbol isLess minSym)
- minSym = pclosure(i)(index(i)).symbol;
+ if (nextBaseType(i).symbol isLess minSym) minSym = nextBaseType(i).symbol;
i = i + 1
}
var minTypes: List[Type] = List();
i = 0;
while (i < nparents) {
- val tp = pclosure(i)(index(i));
+ val tp = nextBaseType(i);
if (tp.symbol == minSym) {
if (!(minTypes exists (tp =:=))) minTypes = tp :: minTypes;
index(i) = index(i) + 1
@@ -589,11 +593,6 @@ import Flags._;
buf += intersectionType(minTypes);
clSize = clSize + 1;
}
- i = 0;
- while (i < nparents) {
- assert(index(i) == pclosure(i).length);
- i = i + 1
- }
}
closureCache = new Array[Type](clSize);
buf.copyToArray(closureCache, 0);
@@ -693,8 +692,8 @@ import Flags._;
/** A class representing a class info
*/
case class ClassInfoType(override val parents: List[Type],
- override val decls: Scope,
- override val symbol: Symbol) extends CompoundType;
+ override val decls: Scope,
+ override val symbol: Symbol) extends CompoundType;
class PackageClassInfoType(decls: Scope, clazz: Symbol) extends ClassInfoType(List(), decls, clazz);
@@ -853,7 +852,7 @@ import Flags._;
override def narrow: Type = resultType.narrow;
override def toString(): String =
- (if (typeParams.isEmpty) "=>! "
+ (if (typeParams.isEmpty) "=> "
else (typeParams map (.defString)).mkString("[", ",", "]")) + resultType;
override def cloneInfo(owner: Symbol) = {
@@ -963,6 +962,8 @@ import Flags._;
val sym1 = if (sym.isAbstractType) rebind(pre, sym) else sym;
if (checkMalformedSwitch && sym1.isAbstractType && !pre.isStable && !pre.isError)
throw new MalformedType(pre, sym.nameString);
+// if (sym1.hasFlag(LOCKED))
+// throw new TypeError("illegal cyclic reference involving " + sym1);
if (sym1.isAliasType && sym1.info.typeParams.length == args.length) {
// note: we require that object is initialized,
// that's why we use info.typeParams instead of typeParams.
@@ -1475,8 +1476,17 @@ import Flags._;
tps1.length == tps2.length &&
List.forall2(tps1, tps2)((tp1, tp2) => tp1 =:= tp2);
- /** Does tp1 conform to tp2? */
+ var subtypecount = 0;
def isSubType(tp1: Type, tp2: Type): boolean = {
+ subtypecount = subtypecount + 1;
+ if (subtypecount == 20) throw new Error("recursive <:<");
+ val result = isSubType0(tp1, tp2);
+ subtypecount = subtypecount - 1;
+ result
+ }
+
+ /** Does tp1 conform to tp2? */
+ def isSubType0(tp1: Type, tp2: Type): boolean = {
Pair(tp1, tp2) match {
case Pair(ErrorType, _) => true
case Pair(WildcardType, _) => true
diff --git a/sources/scala/tools/nsc/transform/Erasure.scala b/sources/scala/tools/nsc/transform/Erasure.scala
index b14b939e70..188a3c8163 100755
--- a/sources/scala/tools/nsc/transform/Erasure.scala
+++ b/sources/scala/tools/nsc/transform/Erasure.scala
@@ -156,7 +156,8 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
typed {
atPos(tree.pos) {
if (pt.symbol == UnitClass) {
- Literal(())
+ if (treeInfo.isPureExpr(tree)) Literal(())
+ else Block(List(tree), Literal(()))
} else if (pt.symbol == BooleanClass) {
val tree1 = adaptToType(tree, boxedClass(BooleanClass).tpe);
Apply(Select(tree1, "booleanValue"), List())
@@ -279,19 +280,19 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
/** A replacement for the standard typer's `typed1' method */
override protected def typed1(tree: Tree, mode: int, pt: Type): Tree = {
val tree1 = super.typed1(adaptMember(tree), mode, pt);
+ def adaptCase(cdef: CaseDef): CaseDef = {
+ val body1 = adaptToType(cdef.body, tree1.tpe);
+ copy.CaseDef(cdef, cdef.pat, cdef.guard, body1) setType body1.tpe
+ }
+ def adaptBranch(branch: Tree): Tree =
+ if (branch == EmptyTree) branch else adaptToType(branch, tree1.tpe);
tree1 match {
case If(cond, thenp, elsep) =>
- val thenp1 = adaptToType(thenp, tree1.tpe);
- val elsep1 = if (elsep.isEmpty) elsep else adaptToType(elsep, tree1.tpe);
- copy.If(tree1, cond, thenp1, elsep1);
+ copy.If(tree1, cond, adaptBranch(thenp), adaptBranch(elsep))
case Match(selector, cases) =>
- val cases1 = cases map {
- case cdef @ CaseDef(pat, guard, body) =>
- val body1 = adaptToType(body, tree1.tpe);
- copy.CaseDef(cdef, pat, guard, body1) setType body1.tpe
- }
- copy.Match(tree1, selector, cases1)
- // todo: do same for try
+ copy.Match(tree1, selector, cases map adaptCase)
+ case Try(block, catches, finalizer) =>
+ copy.Try(tree1, adaptBranch(block), catches map adaptCase, finalizer)
case _ =>
tree1
}
@@ -311,8 +312,8 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
*/
private def checkNoDoubleDefs(root: Symbol): unit = {
def doubleDefError(sym1: Symbol, sym2: Symbol) = {
- val tpe1 = atPhase(currentRun.refchecksPhase.next)(root.tpe.memberType(sym1));
- val tpe2 = atPhase(currentRun.refchecksPhase.next)(root.tpe.memberType(sym2));
+ val tpe1 = atPhase(currentRun.refchecksPhase.next)(root.thisType.memberType(sym1));
+ val tpe2 = atPhase(currentRun.refchecksPhase.next)(root.thisType.memberType(sym2));
unit.error(
if (sym1.owner == root) sym1.pos else root.pos,
(if (sym1.owner == sym2.owner) "double definition:\n"
@@ -420,6 +421,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
resetFlag ACCESSOR
setInfo otpe;
bridgeTarget(bridge) = member;
+ owner.info.decls.enter(bridge);
bridgesScope enter bridge;
bridges =
atPhase(phase.next) {
diff --git a/sources/scala/tools/nsc/transform/Mixin.scala b/sources/scala/tools/nsc/transform/Mixin.scala
index 38f4fb963c..6fecdedcba 100755
--- a/sources/scala/tools/nsc/transform/Mixin.scala
+++ b/sources/scala/tools/nsc/transform/Mixin.scala
@@ -100,7 +100,8 @@ abstract class Mixin extends InfoTransform {
if (bc.isImplClass) {
for (val member <- bc.info.decls.toList) {
if (isForwarded(member) && !isStatic(member) &&
- (clazz.info.member(member.name).alternatives contains member)) {
+ (clazz.info.findMember(member.name, 0, 0).alternatives contains member)) {
+ //System.out.println("adding forwarded method " + member + member.locationString + " to " + clazz + " " + clazz.info.member(member.name).alternatives);//DEBUG
val member1 = addMember(clazz, member.cloneSymbol(clazz) setFlag MIXEDIN resetFlag (DEFERRED | lateDEFERRED));
member1.asInstanceOf[TermSymbol] setAlias member;
}
diff --git a/sources/scala/tools/nsc/typechecker/Infer.scala b/sources/scala/tools/nsc/typechecker/Infer.scala
index fc45a72425..14ea5dbd16 100755
--- a/sources/scala/tools/nsc/typechecker/Infer.scala
+++ b/sources/scala/tools/nsc/typechecker/Infer.scala
@@ -223,10 +223,13 @@ package scala.tools.nsc.typechecker;
} else {
val sym1 = sym filter (alt => context.isAccessible(alt, pre, site.isInstanceOf[Super]));
if (sym1 == NoSymbol) {
- if (settings.debug.value) System.out.println(context);//debug
- System.out.println(tree);//debug
- System.out.println("" + pre + " " + sym.owner + " " + context.owner + " " + context.outer.enclClass.owner + " " + sym.owner.thisType + (pre =:= sym.owner.thisType));//debug
- errorTree(tree, sym.toString() + " cannot be accessed in " + pre.widen)
+ if (settings.debug.value) {
+ System.out.println(context);//debug
+ System.out.println(tree);//debug
+ System.out.println("" + pre + " " + sym.owner + " " + context.owner + " " + context.outer.enclClass.owner + " " + sym.owner.thisType + (pre =:= sym.owner.thisType));//debug
+ }
+ errorTree(tree, sym.toString() + " cannot be accessed in " +
+ (if (sym.isClassConstructor) context.enclClass.owner else pre.widen))
} else {
var owntype = pre.memberType(sym1);
if (pre.isInstanceOf[SuperType])
@@ -455,7 +458,6 @@ package scala.tools.nsc.typechecker;
uninstantiated.toList;
} catch {
case ex: NoInstance =>
- System.out.println("error " + fn.pos + " " + fn);//debug
errorTree(fn,
"no type parameters for " +
applyErrorMsg(
diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala
index 9f9243eb26..3b6f353714 100755
--- a/sources/scala/tools/nsc/typechecker/Namers.scala
+++ b/sources/scala/tools/nsc/typechecker/Namers.scala
@@ -271,7 +271,7 @@ trait Namers: Analyzer {
private def templateSig(templ: Template): Type = {
val clazz = context.owner;
- val parents = typer.parentTypes(templ) map (.tpe);
+ val parents = typer.parentTypes(templ) map (p => if (p.tpe.isError) AnyRefClass.tpe else p.tpe);
val decls = new Scope();
log("members of " + clazz + "=" + decls.hashCode());//debug
new Namer(context.make(templ, clazz, decls)).enterSyms(templ.body);
@@ -399,6 +399,7 @@ trait Namers: Analyzer {
checkSelectors(rest)
case Nil =>
}
+ checkSelectors(selectors);
ImportType(expr1)
}
} catch {
diff --git a/sources/scala/tools/nsc/typechecker/RefChecks.scala b/sources/scala/tools/nsc/typechecker/RefChecks.scala
index 4cd609d909..eb3ea846e8 100755
--- a/sources/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/sources/scala/tools/nsc/typechecker/RefChecks.scala
@@ -246,8 +246,7 @@ abstract class RefChecks extends InfoTransform {
for (val member <- clazz.info.decls.toList)
if ((member hasFlag (OVERRIDE | ABSOVERRIDE)) &&
(clazz.info.baseClasses.tail forall (bc => member.overriddenSymbol(bc) == NoSymbol))) {
- for (val bc <- clazz.info.baseClasses.tail)
- System.out.println("" + bc + " has " + bc.info.decl(member.name) + ":" + bc.info.decl(member.name).tpe);//debug
+ // for (val bc <- clazz.info.baseClasses.tail) System.out.println("" + bc + " has " + bc.info.decl(member.name) + ":" + bc.info.decl(member.name).tpe);//DEBUG
unit.error(member.pos, member.toString() + " overrides nothing");
member resetFlag OVERRIDE
}
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index 0356cd7bd6..181dbba00d 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -126,6 +126,37 @@ import collection.mutable.HashMap;
if (treeInfo.isPureExpr(tree) || tree.tpe.isError) tree;
else errorTree(tree, "stable identifier required, but " + tree + " found.");
+ /** Check that type `tp' is not a subtype of itself.
+ */
+ def checkNonCyclic(pos: int, tp: Type): unit = {
+ def checkNotLocked(sym: Symbol): boolean = {
+ sym.initialize;
+ if (sym hasFlag LOCKED) {
+ error(pos, "cyclic aliasing or subtyping involving " + sym); false
+ } else true
+ }
+ tp match {
+ case TypeRef(pre, sym, args) =>
+ if (checkNotLocked(sym) && (sym.isAliasType || sym.isAbstractType)) {
+ //System.out.println("checking " + sym);//DEBUG
+ checkNonCyclic(pos, pre.memberInfo(sym).subst(sym.typeParams, args), sym);
+ }
+ case SingleType(pre, sym) =>
+ checkNotLocked(sym)
+ case st: SubType =>
+ checkNonCyclic(pos, st.supertype)
+ case ct: CompoundType =>
+ for (val p <- ct.parents) checkNonCyclic(pos, p)
+ case _ =>
+ }
+ }
+
+ def checkNonCyclic(pos: int, tp: Type, lockedSym: Symbol): unit = {
+ lockedSym.setFlag(LOCKED);
+ checkNonCyclic(pos, tp);
+ lockedSym.resetFlag(LOCKED)
+ }
+
/** Check that type of given tree does not contain local or private components
*/
object checkNoEscaping extends TypeMap {
@@ -338,8 +369,9 @@ import collection.mutable.HashMap;
" does not conform to sequence " + clazz)
}
} else {
- System.out.println("bad: " + clazz + ":" + tree.tpe + " " + flagsToString(clazz.flags) + clazz.hasFlag(CASE));//debug
- errorTree(tree, clazz.toString() + " is neither a case class nor a sequence class")
+ if (!tree.tpe.isError)
+ error(tree.pos, clazz.toString() + " is neither a case class nor a sequence class");
+ setError(tree)
}
}
} else if ((mode & FUNmode) != 0) {
@@ -402,7 +434,7 @@ import collection.mutable.HashMap;
tree.tpe
}
- def parentTypes(templ: Template): List[Tree] =
+ def parentTypes(templ: Template): List[Tree] = try {
if (templ.parents.isEmpty) List()
else {
var supertpt = typedTypeConstructor(templ.parents.head);
@@ -431,6 +463,11 @@ import collection.mutable.HashMap;
//System.out.println("parents(" + context.owner + ") = " + supertpt :: mixins);//DEBUG
List.mapConserve(supertpt :: mixins)(tpt => checkNoEscaping.privates(context.owner, tpt))
}
+ } catch {
+ case ex: TypeError =>
+ reportTypeError(templ.pos, ex);
+ List(TypeTree(AnyRefClass.tpe))
+ }
/** Check that
* - all parents are class types,
@@ -459,7 +496,7 @@ import collection.mutable.HashMap;
else if (psym.isSealed && !phase.erasedTypes) {
// are we in same scope as base type definition?
val e = defscope.lookupEntry(psym.name);
- if (!(e.sym == psym && e.owner == defscope)) {
+ if (!(e != null && e.sym == psym && e.owner == defscope)) {
// we are not within same statement sequence
var c = context;
while (c != NoContext && c.owner != psym) c = c.outer.enclClass;
@@ -559,6 +596,7 @@ import collection.mutable.HashMap;
def typedValDef(vdef: ValDef): ValDef = {
val sym = vdef.symbol;
var tpt1 = checkNoEscaping.privates(sym, typedType(vdef.tpt));
+ checkNonCyclic(vdef.pos, tpt1.tpe, sym);
val rhs1 =
if (vdef.rhs.isEmpty) {
if (sym.isVariable && sym.owner.isTerm && phase.id <= currentRun.typerPhase.id)
@@ -628,7 +666,16 @@ import collection.mutable.HashMap;
val tparams1 = List.mapConserve(ddef.tparams)(typedAbsTypeDef);
val vparamss1 = List.mapConserve(ddef.vparamss)(vparams1 =>
List.mapConserve(vparams1)(typedValDef));
- var tpt1 = checkNoEscaping.privates(meth, typedType(ddef.tpt));
+/*
+ for (val vparams <- vparamss1; val vparam <- vparams) {
+ checkNoEscaping.locals(paramScope, WildcardType, vparam.tpt); ()
+ }
+*/
+ var tpt1 =
+// checkNoEscaping.locals(context.scope, WildcardType,
+ checkNoEscaping.privates(meth,
+ typedType(ddef.tpt));
+ checkNonCyclic(ddef.pos, tpt1.tpe, meth);
val rhs1 =
checkNoEscaping.locals(
context.scope, tpt1.tpe,
@@ -642,7 +689,7 @@ import collection.mutable.HashMap;
context.enclClass.owner.setFlag(INCONSTRUCTOR);
val result = typed(ddef.rhs, EXPRmode | INCONSTRmode, UnitClass.tpe);
context.enclClass.owner.resetFlag(INCONSTRUCTOR);
- if (meth.isPrimaryConstructor && !phase.erasedTypes)
+ if (meth.isPrimaryConstructor && !phase.erasedTypes && reporter.errors() == 0)
computeParamAliases(meth.owner, vparamss1, result);
result
} else transformedOrTyped(ddef.rhs, tpt1.tpe));
@@ -652,6 +699,7 @@ import collection.mutable.HashMap;
def typedAbsTypeDef(tdef: AbsTypeDef): AbsTypeDef = {
val lo1 = checkNoEscaping.privates(tdef.symbol, typedType(tdef.lo));
val hi1 = checkNoEscaping.privates(tdef.symbol, typedType(tdef.hi));
+ checkNonCyclic(tdef.pos, tdef.symbol.tpe);
copy.AbsTypeDef(tdef, tdef.mods, tdef.name, lo1, hi1) setType NoType
}
@@ -659,6 +707,7 @@ import collection.mutable.HashMap;
reenterTypeParams(tdef.tparams);
val tparams1 = List.mapConserve(tdef.tparams)(typedAbsTypeDef);
val rhs1 = checkNoEscaping.privates(tdef.symbol, typedType(tdef.rhs));
+ checkNonCyclic(tdef.pos, tdef.symbol.tpe);
copy.AliasTypeDef(tdef, tdef.mods, tdef.name, tparams1, rhs1) setType NoType
}
@@ -734,7 +783,10 @@ import collection.mutable.HashMap;
vparam.symbol
}
val vparams = List.mapConserve(fun.vparams)(typedValDef);
- val body = typed(fun.body, respt);
+ for (val vparam <- vparams) {
+ checkNoEscaping.locals(context.scope, WildcardType, vparam.tpt); ()
+ }
+ val body = checkNoEscaping.locals(context.scope, respt, typed(fun.body, respt));
val formals = vparamSyms map (.tpe);
val restpe = body.tpe.deconst;
val funtpe = typeRef(clazz.tpe.prefix, clazz, formals ::: List(restpe));
@@ -757,6 +809,7 @@ import collection.mutable.HashMap;
stat match {
case imp @ Import(_, _) =>
context = context.makeNewImport(imp);
+ stat.symbol.initialize;
EmptyTree
case _ =>
(if (exprOwner != context.owner && (!stat.isDef || stat.isInstanceOf[LabelDef]))
@@ -798,7 +851,7 @@ import collection.mutable.HashMap;
case MethodType(formals0, restpe) =>
val formals = formalTypes(formals0, args.length);
if (formals.length != args.length) {
- System.out.println("" + formals.length + " " + args.length);
+ //System.out.println("" + formals.length + " " + args.length);//DEBUG
errorTree(tree, "wrong number of arguments for " + treeSymTypeMsg(fun))
} else {
val tparams = context.undetparams;
@@ -986,7 +1039,6 @@ import collection.mutable.HashMap;
pre = qual.tpe;
} else {
if (settings.debug.value) {
- log(context);//debug
log(context.imports);//debug
}
error(tree.pos, "not found: " + decode(name));
@@ -1068,9 +1120,9 @@ import collection.mutable.HashMap;
case Bind(name, body) =>
var vble = tree.symbol;
if (vble == NoSymbol) vble = context.owner.newValue(tree.pos, name);
+ if (vble.name != nme.WILDCARD) namer.enterInScope(vble);
val body1 = typed(body, mode, pt);
vble.setInfo(if (treeInfo.isSequenceValued(body)) seqType(body1.tpe) else body1.tpe);
- if (vble.name != nme.WILDCARD) namer.enterInScope(vble);
copy.Bind(tree, name, body1) setSymbol vble setType body1.tpe; // buraq, was: pt
case ArrayValue(elemtpt, elems) =>
@@ -1158,6 +1210,7 @@ import collection.mutable.HashMap;
setPos tpt1.pos
setType appliedType(tpt1.tpe, context.undetparams map (.tpe));
}
+ if (tpt1.tpe.symbol.isTrait) error(tree.pos, "traits cannot be instantiated");
copy.New(tree, tpt1).setType(tpt1.tpe)
case Typed(expr, tpt @ Ident(name)) if (name == nme.WILDCARD_STAR.toTypeName) =>
@@ -1342,9 +1395,13 @@ import collection.mutable.HashMap;
def typedType(tree: Tree): Tree =
typed(tree, TYPEmode, WildcardType);
- /** Types a type or type constructor tree */
- def typedTypeConstructor(tree: Tree): Tree =
- typed(tree, TYPEmode | FUNmode, WildcardType);
+ /** Types a type constructor tree used in a new or supertype */
+ def typedTypeConstructor(tree: Tree): Tree = {
+ val result = typed(tree, TYPEmode | FUNmode, WildcardType);
+ if (!phase.erasedTypes && result.tpe.isInstanceOf[TypeRef] && !result.tpe.prefix.isStable)
+ error(tree.pos, result.tpe.prefix.toString() + " is not a legal prefix for a constructor");
+ result
+ }
def computeType(tree: Tree): Type = {
val tree1 = typed(tree);
@@ -1427,8 +1484,8 @@ import collection.mutable.HashMap;
" both " + is0.head.sym + is0.head.sym.locationString + " of type " + tree.tpe +
"\n and " + is.head.sym + is.head.sym.locationString + " of type " + tree1.tpe +
(if (isView)
- "\n are possible conversion functions from " +
- pt.typeArgs(0) + " to " + pt.typeArgs(1)
+ "\n are possible conversion functions from " +
+ pt.typeArgs(0) + " to " + pt.typeArgs(1)
else
"\n match expected type " + pt));
}