From d14841d095448f0c7c2b211de8ca6f0e218c1f51 Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Mon, 15 Feb 2010 10:12:00 +0000 Subject: Merge branch 'fix-specialized' --- .../scala/tools/nsc/ast/TreePrinters.scala | 2 - .../tools/nsc/transform/SpecializeTypes.scala | 52 +++++++++++++++------- .../scala/tools/nsc/typechecker/Duplicators.scala | 2 +- 3 files changed, 37 insertions(+), 19 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala index fd5a5b391e..cb899a2560 100644 --- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala @@ -136,8 +136,6 @@ trait TreePrinters { trees: SymbolTable => else tree.asInstanceOf[MemberDef].mods.annotations annots foreach (annot => print("@"+annot+" ")) - if (annots.nonEmpty) - println() } def print(str: String) { out.print(str) } diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 5792b5432b..b2dd77ccfa 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -430,7 +430,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } info(specMember) = Forward(om) - info(om) = Implementation(original) + info(om) = if (original.isDeferred) Forward(original) else Implementation(original) + log("forwardToOverlad: " + " original.isDeferred: " + original.isDeferred + " info(om): " + info(om)) typeEnv(om) = env ++ typeEnv(m) // add the environment for any method tparams enterMember(om) @@ -669,10 +670,20 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { && opc.overridden.owner.info.decl(specializedName(opc.overridden, env)) != NoSymbol) { log("Added specialized overload for " + opc.overriding.fullName + " in env: " + env) val om = specializedOverload(clazz, opc.overridden, env) + typeEnv(om) = env if (!opc.overriding.isDeferred) { concreteSpecMethods += opc.overriding - info(om) = Implementation(opc.overriding) + // if the override is a normalized member, 'om' gets the implementation from + // its original target, and adds the environment of the normalized member (that is, + // any specialized /method/ type parameter bindings) + info(om) = info.get(opc.overriding) match { + case Some(NormalizedMember(target)) => + typeEnv(om) = env ++ typeEnv(opc.overriding) + Implementation(target) + case None => Implementation(opc.overriding) + } info(opc.overriding) = Forward(om) + log("typeEnv(om) = " + typeEnv(om)) } overloads(opc.overriding) = Overload(om, env) :: overloads(opc.overriding) oms += om @@ -789,8 +800,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { PolyType(targs, ClassInfoType(parents, new Scope(specializeClass(clazz, typeEnv(clazz))), clazz)) case ClassInfoType(base, decls, clazz) if !clazz.isPackageClass => -// val parents = base map specializedType - log("transformInfo " + clazz ) + val parents = base map specializedType + log("transformInfo " + clazz + " with parents1: " + parents) val res = ClassInfoType(base map specializedType, new Scope(specializeClass(clazz, typeEnv(clazz))), clazz) res @@ -813,7 +824,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { */ def conflicting(env: TypeEnv, warn: (Position, String) => Unit): Boolean = env exists { case (tvar, tpe) => - if (!(subst(env, tvar.info.bounds.lo) <:< tpe) && (tpe <:< subst(env, tvar.info.bounds.hi))) { + if (!((subst(env, tvar.info.bounds.lo) <:< tpe) + && (tpe <:< subst(env, tvar.info.bounds.hi)))) { warn(tvar.pos, "Bounds prevent specialization for " + tvar) true } else false @@ -939,8 +951,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case None => super.transform(tree) } - case Select(qual, name) if (/*!symbol.isMethod - &&*/ !specializedTypeVars(symbol.info).isEmpty + case Select(qual, name) if (!specializedTypeVars(symbol.info).isEmpty && name != nme.CONSTRUCTOR) => val qual1 = transform(qual) log("checking for unification at " + tree + " with sym.tpe: " + symbol.tpe + " and tree.tpe: " + tree.tpe + " at " + tree.pos.line) @@ -974,7 +985,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val specMembers = makeSpecializedMembers(tree.symbol.enclClass) ::: (implSpecClasses(body) map localTyper.typed) if (!symbol.isPackageClass) (new CollectMethodBodies)(tree) - treeCopy.Template(tree, parents, self, atOwner(currentOwner)(transformTrees(body ::: specMembers))) + treeCopy.Template(tree, currentOwner.info.parents.map(TypeTree), self, + atOwner(currentOwner)(transformTrees(body ::: specMembers))) case ddef @ DefDef(mods, name, tparams, vparamss, tpt, rhs) if info.isDefinedAt(symbol) => if (symbol.isConstructor) { @@ -998,7 +1010,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case NormalizedMember(target) => log("normalized member " + symbol + " of " + target) - if (conflicting(typeEnv(symbol))) { + if (target.isDeferred || conflicting(typeEnv(symbol))) { +/* val targs = makeTypeArguments(symbol, target) log("targs: " + targs) val call = @@ -1013,10 +1026,12 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { maybeCastTo(symbol.info.finalResultType, target.info.subst(target.info.typeParams, targs).finalResultType, call))) +*/ -/* copy.DefDef(tree, mods, name, tparams, vparamss, tpt, - typed(Apply(gen.mkAttributedRef(definitions.Predef_error), - List(Literal("boom! you stepped on a bug. This method should never be called.")))))*/ + treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, + localTyper.typed( + Apply(gen.mkAttributedRef(definitions.Predef_error), + List(Literal("boom! you stepped on a bug. This method should never be called."))))) } else { // we have an rhs, specialize it val tree1 = duplicateBody(ddef, target) @@ -1062,6 +1077,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { symbol.enclClass, typeEnv(symbol.alias) ++ typeEnv(tree.symbol)) + case Apply(Select(Super(qual, name), name1), args) => + val res = localTyper.typed(Apply(Select(Super(qual, name), name1), args)) + log("retyping call to super, from: " + symbol + " to " + res.symbol) + res + case _ => super.transform(tree) } @@ -1160,10 +1180,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { override def transform(tree: Tree): Tree = { val tree1 = super.transform(tree) if (needsCast(tree1)) { - log("inserting cast for " + tree1 + " tpe: " + tree1.tpe) - val tree2 = gen.mkAsInstanceOf(tree1, tree1.tpe.typeSymbol.info.bounds.hi) - log(" casted to: " + tree2) - tree2 +// log("inserting cast for " + tree1 + " tpe: " + tree1.tpe) +// val tree2 = gen.mkAsInstanceOf(tree1, tree1.tpe.typeSymbol.info.bounds.hi) +// log(" casted to: " + tree2) + tree1 } else tree1 } diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala index 6a94189284..40cf9e82c0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala @@ -157,7 +157,7 @@ abstract class Duplicators extends Analyzer { typed(ddef) } - /** Special typer method allowing for re-type checking trees. It expects a typed tree. + /** Special typer method for re-type checking trees. It expects a typed tree. * Returns a typed tree that has fresh symbols for all definitions in the original tree. * * Each definition tree is visited and its symbol added to the invalidSyms map (except LabelDefs), -- cgit v1.2.3