From b10fe9805e2e1c9543c6ce7df7779dbcb1d90a3f Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 16 Oct 2005 07:19:23 +0000 Subject: *** empty log message *** --- sources/scala/tools/nsc/ast/parser/Parsers.scala | 5 +- sources/scala/tools/nsc/symtab/Constants.scala | 2 +- sources/scala/tools/nsc/symtab/Definitions.scala | 9 ++- sources/scala/tools/nsc/symtab/Names.scala | 2 +- sources/scala/tools/nsc/symtab/Symbols.scala | 8 +- sources/scala/tools/nsc/symtab/Types.scala | 44 ++++++----- sources/scala/tools/nsc/transform/Erasure.scala | 28 +++---- sources/scala/tools/nsc/transform/Mixin.scala | 3 +- sources/scala/tools/nsc/typechecker/Infer.scala | 12 +-- sources/scala/tools/nsc/typechecker/Namers.scala | 3 +- .../scala/tools/nsc/typechecker/RefChecks.scala | 3 +- sources/scala/tools/nsc/typechecker/Typers.scala | 87 ++++++++++++++++++---- 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) "" 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)); } -- cgit v1.2.3