summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-11-09 15:52:02 +0000
committerMartin Odersky <odersky@gmail.com>2005-11-09 15:52:02 +0000
commit8a426ccf5f56f2d21ab6bad7d02ec2b1b2532346 (patch)
tree25f206e4bb54429bef68d0e680abc405fab6cbba
parent071be391c1cf77c3e22c33aad8a2e783c59d1574 (diff)
downloadscala-8a426ccf5f56f2d21ab6bad7d02ec2b1b2532346.tar.gz
scala-8a426ccf5f56f2d21ab6bad7d02ec2b1b2532346.tar.bz2
scala-8a426ccf5f56f2d21ab6bad7d02ec2b1b2532346.zip
*** empty log message ***
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala24
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala28
-rwxr-xr-xsources/scala/tools/nsc/transform/Erasure.scala22
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Namers.scala66
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala5
5 files changed, 101 insertions, 44 deletions
diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala
index 92887ac6b6..396f733ca3 100755
--- a/sources/scala/tools/nsc/symtab/Symbols.scala
+++ b/sources/scala/tools/nsc/symtab/Symbols.scala
@@ -84,6 +84,12 @@ import Flags._;
new TypeSymbol(this, pos, name).setFlag(DEFERRED);
final def newTypeParameter(pos: int, name: Name) =
newAbstractType(pos, name).setFlag(PARAM);
+ final def newSkolem(tparam: Symbol) = tparam;// for now
+/*
+ new TypeSkolem(this, tparam.pos, tparam.name, tparam)
+ .setFlag(tparam.flags)
+ .setInfo(tparam.rawInfo);
+*/
final def newClass(pos: int, name: Name) =
new ClassSymbol(this, pos, name);
final def newModuleClass(pos: int, name: Name) =
@@ -104,9 +110,9 @@ import Flags._;
// Tests ----------------------------------------------------------------------
- def isTerm = false; //to be overridden
- def isType = false; //to be overridden
- def isClass = false; //to be overridden
+ def isTerm = false; //to be overridden
+ def isType = false; //to be overridden
+ def isClass = false; //to be overridden
final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA));
final def isVariable = isTerm && hasFlag(MUTABLE) && !isMethod;
@@ -584,6 +590,9 @@ import Flags._;
final def setter(base: Symbol): Symbol =
base.info.decl(nme.getterToSetter(nme.getterName(name))) filter (.hasFlag(ACCESSOR));
+ /** If this symbol is a skolem, its corresponding type parameter, otherwise this */
+ def deSkolemize: Symbol = this;
+
/** Remove private modifier from symbol `sym's definition. If `sym' is a
* term symbol rename it by expanding its name to avoid name clashes
*/
@@ -859,6 +868,15 @@ import Flags._;
if (util.Statistics.enabled) typeSymbolCount = typeSymbolCount + 1;
}
+ /** A class for type parameters viewed from inside their scopes */
+ class TypeSkolem(initOwner: Symbol, initPos: int, initName: Name, typeParam: Symbol) extends TypeSymbol(initOwner, initPos, initName) {
+ override def deSkolemize = typeParam;
+ override def cloneSymbolImpl(owner: Symbol): Symbol = {
+ throw new Error("should not clone a type skolem");
+ }
+ override def toString(): String = super.toString() + "&";
+ }
+
/** A class for class symbols */
class ClassSymbol(initOwner: Symbol, initPos: int, initName: Name) extends TypeSymbol(initOwner, initPos, initName) {
var sourceFile: AbstractFile = null;
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index d4df21fd0a..5aa43e088e 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -1172,7 +1172,7 @@ import Flags._;
val symclazz = sym.owner;
def throwError =
throw new Error("" + tp + " in " + symclazz +
- "cannot be instantiated from " + pre.widen);
+ " cannot be instantiated from " + pre.widen);
def instParam(ps: List[Symbol], as: List[Type]): Type =
if (ps.isEmpty) throwError
else if (sym eq ps.head) as.head
@@ -1346,6 +1346,32 @@ import Flags._;
}
}
+ /** Convert to corresponding type parameters all skolems which satisfy one of the
+ * following two conditions:
+ * 1. The skolem is a parameter of a class or alias type
+ * 2. The skolem is a method parameter which appears in parameter `tparams'
+ */
+ class DeSkolemizeMap(tparams: List[Symbol]) extends TypeMap {
+ def apply(tp: Type): Type = tp;//for now
+ /*
+ tp match {
+ case TypeRef(pre, sym, args) =>
+ val tparam = sym.deSkolemize;
+ mapOver(
+ if (tparam == sym || tparam.owner.isTerm && !(tparams contains tparam)) tp
+ else rawTypeRef(pre, tparam, args))
+ case PolyType(tparams1, restpe) =>
+ assert(tparams.isEmpty);
+ new DeSkolemizeMap(tparams1).mapOver(tp)
+ case ClassInfoType(_, _, _) =>
+ tp
+ case _ =>
+ mapOver(tp)
+ }
+ */
+ }
+ val deSkolemize = new DeSkolemizeMap(List());
+
// Helper Methods -------------------------------------------------------------
final def isValid(p: Phase): boolean =
diff --git a/sources/scala/tools/nsc/transform/Erasure.scala b/sources/scala/tools/nsc/transform/Erasure.scala
index 659b12ff5c..21b2c6b642 100755
--- a/sources/scala/tools/nsc/transform/Erasure.scala
+++ b/sources/scala/tools/nsc/transform/Erasure.scala
@@ -199,7 +199,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
/** Adapt `tree' to expected type `pt' */
private def adaptToType(tree: Tree, pt: Type): Tree = {
- //if (settings.debug.value && pt != WildcardType) log("adapting " + tree + ":" + tree.tpe + " to " + pt);//DEBUG
+ if (settings.debug.value && pt != WildcardType) log("adapting " + tree + ":" + tree.tpe + " to " + pt);//debug
if (tree.tpe <:< pt)
tree
else if (isUnboxedClass(tree.tpe.symbol) && !isUnboxedClass(pt.symbol))
@@ -239,15 +239,17 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
atPos(tree.pos) {
Typed(Apply(Select(New(TypeTree(BoxedAnyArrayClass.tpe)), name), args), tpt)
}
- case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) =>
- if ((tree.symbol == Any_asInstanceOf || tree.symbol == Any_asInstanceOfErased) &&
- isValueClass(targ.tpe.symbol)) {
- val qual1 = typedQualifier(qual);
- if (isNumericValueClass(qual1.tpe.symbol) && isNumericValueClass(targ.tpe.symbol))
- // convert numeric type casts
- atPos(tree.pos)(Apply(Select(qual1, "to" + targ.tpe.symbol.name), List()))
- else unbox(qual1, targ.tpe)
- } else tree
+ case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List())
+ if ((tree.symbol == Any_asInstanceOf || tree.symbol == Any_asInstanceOfErased)) =>
+ val qual1 = typedQualifier(qual);
+ val targClass = targ.tpe.symbol;
+ if (isNumericValueClass(qual1.tpe.symbol) && isNumericValueClass(targClass))
+ // convert numeric type casts
+ atPos(tree.pos)(Apply(Select(qual1, "to" + targClass.name), List()))
+ else if (isValueClass(targClass) ||
+ (targClass == ArrayClass && (qual1.tpe <:< BoxedArrayClass.tpe)))
+ unbox(qual1, targ.tpe)
+ else tree
case Select(qual, name) if (name != nme.CONSTRUCTOR) =>
if (tree.symbol == Any_asInstanceOf || tree.symbol == Any_asInstanceOfErased)
adaptMember(atPos(tree.pos)(Select(qual, Object_asInstanceOf)))
diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala
index 3b6f353714..abe7d05a32 100755
--- a/sources/scala/tools/nsc/typechecker/Namers.scala
+++ b/sources/scala/tools/nsc/typechecker/Namers.scala
@@ -125,6 +125,10 @@ trait Namers: Analyzer {
}
def finish = finishWith(List());
+ def skolemize(tparams: List[AbsTypeDef]): unit = {
+ for (val tp <- tparams) tp.symbol = context.owner.newSkolem(tp.symbol)
+ }
+
if (tree.symbol == NoSymbol) {
val owner = context.owner;
tree match {
@@ -141,7 +145,8 @@ trait Namers: Analyzer {
}
val mods1: int = if (impl.body forall treeInfo.isInterfaceMember) mods | INTERFACE else mods;
tree.symbol = enterClassSymbol(tree.pos, mods1, name);
- finishWith(tparams)
+ finishWith(tparams);
+ skolemize(tparams);
case ModuleDef(mods, name, _) =>
tree.symbol = enterModuleSymbol(tree.pos, mods | MODULE | FINAL, name);
tree.symbol.moduleClass.setInfo(innerNamer.typeCompleter(tree));
@@ -174,10 +179,12 @@ trait Namers: Analyzer {
case DefDef(mods, nme.CONSTRUCTOR, tparams, vparams, tp, rhs) =>
tree.symbol = enterInScope(owner.newConstructor(tree.pos))
.setFlag(mods | owner.getFlag(ConstrFlags));
- finishWith(tparams)
+ finishWith(tparams);
+ skolemize(tparams);
case DefDef(mods, name, tparams, _, _, _) =>
tree.symbol = enterInScope(owner.newMethod(tree.pos, name)).setFlag(mods);
- finishWith(tparams)
+ finishWith(tparams);
+ skolemize(tparams);
case AbsTypeDef(mods, name, _, _) =>
tree.symbol = enterInScope(owner.newAbstractType(tree.pos, name)).setFlag(mods);
finish
@@ -346,7 +353,7 @@ trait Namers: Analyzer {
private def aliasTypeSig(tpsym: Symbol, tparams: List[AbsTypeDef], rhs: Tree): Type =
makePolyType(typer.reenterTypeParams(tparams), typer.typedType(rhs).tpe);
- private def typeSig(tree: Tree): Type =
+ private def typeSig(tree: Tree): Type = deSkolemize {
try {
val sym: Symbol = tree.symbol;
tree match {
@@ -355,9 +362,9 @@ trait Namers: Analyzer {
case ModuleDef(_, _, impl) =>
val clazz = sym.moduleClass;
- clazz.setInfo(new Namer(context.make(tree, clazz)).templateSig(impl));
- //clazz.typeOfThis = singleType(sym.owner.thisType, sym);
- clazz.tpe;
+ clazz.setInfo(new Namer(context.make(tree, clazz)).templateSig(impl));
+ //clazz.typeOfThis = singleType(sym.owner.thisType, sym);
+ clazz.tpe;
case DefDef(_, _, tparams, vparamss, tpt, rhs) =>
if (sym.isConstructor) sym.owner.setFlag(INCONSTRUCTOR);
@@ -367,46 +374,47 @@ trait Namers: Analyzer {
checkContractive(sym, result)
case ValDef(_, _, tpt, rhs) =>
- if (tpt.isEmpty)
- if (rhs.isEmpty) {
+ if (tpt.isEmpty)
+ if (rhs.isEmpty) {
context.error(tpt.pos, "missing parameter type");
- ErrorType
- } else {
- tpt.tpe = deconstIfNotFinal(sym, newTyper(context.make(tree, sym)).computeType(rhs));
- tpt.tpe
- }
- else typer.typedType(tpt).tpe
+ ErrorType
+ } else {
+ tpt.tpe = deconstIfNotFinal(sym, newTyper(context.make(tree, sym)).computeType(rhs));
+ tpt.tpe
+ }
+ else typer.typedType(tpt).tpe
case AliasTypeDef(_, _, tparams, rhs) =>
- new Namer(context.makeNewScope(tree, sym)).aliasTypeSig(sym, tparams, rhs)
+ new Namer(context.makeNewScope(tree, sym)).aliasTypeSig(sym, tparams, rhs)
case AbsTypeDef(_, _, lo, hi) =>
- TypeBounds(typer.typedType(lo).tpe, typer.typedType(hi).tpe);
+ TypeBounds(typer.typedType(lo).tpe, typer.typedType(hi).tpe);
- case Import(expr, selectors) =>
- val expr1 = typer.typedQualifier(expr);
+ case Import(expr, selectors) =>
+ val expr1 = typer.typedQualifier(expr);
val base = expr1.tpe;
- typer.checkStable(expr1);
- def checkSelectors(selectors: List[Pair[Name, Name]]): unit = selectors match {
- case Pair(from, to) :: rest =>
- if (from != nme.WILDCARD && base != ErrorType &&
+ typer.checkStable(expr1);
+ def checkSelectors(selectors: List[Pair[Name, Name]]): unit = selectors match {
+ case Pair(from, to) :: rest =>
+ if (from != nme.WILDCARD && base != ErrorType &&
base.member(from) == NoSymbol && base.member(from.toTypeName) == NoSymbol)
- context.error(tree.pos, from.decode + " is not a member of " + expr);
+ context.error(tree.pos, from.decode + " is not a member of " + expr);
if (from != nme.WILDCARD && (rest.exists (sel => sel._1 == from)))
context.error(tree.pos, from.decode + " is renamed twice");
- if (to != null && to != nme.WILDCARD && (rest exists (sel => sel._2 == to)))
+ if (to != null && to != nme.WILDCARD && (rest exists (sel => sel._2 == to)))
context.error(tree.pos, to.decode + " appears twice as a target of a renaming");
- checkSelectors(rest)
- case Nil =>
+ checkSelectors(rest)
+ case Nil =>
}
checkSelectors(selectors);
- ImportType(expr1)
- }
+ ImportType(expr1)
+ }
} catch {
case ex: TypeError =>
typer.reportTypeError(tree.pos, ex);
ErrorType
}
+ }
/** Check that symbol's definition is well-formed. This means:
* - no conflicting modifiers
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index 8cddbef7fb..520272920c 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -215,7 +215,10 @@ import collection.mutable.HashMap;
for (val vparams <- vparamss; val vparam <- vparams) context.scope enter vparam.symbol;
def reenterTypeParams(tparams: List[AbsTypeDef]): List[Symbol] =
- for (val tparam <- tparams) yield { context.scope enter tparam.symbol; tparam.symbol }
+ for (val tparam <- tparams) yield {
+ context.scope enter tparam.symbol;
+ tparam.symbol.deSkolemize
+ }
def attrInfo(attr: Tree): AttrInfo = attr match {
case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) =>