From dd8009b190fc1f53f98f1313b6292579af79e309 Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Fri, 7 Aug 2009 16:15:44 +0000 Subject: Fixed specialization of lazy values. --- .../tools/nsc/transform/SpecializeTypes.scala | 29 ++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index d1ca4de2ca..736bd6d879 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -426,8 +426,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { // specialized members have to be overridable. Fields should not // have the field CASEACCESSOR (messes up patmatch) - if (m.hasFlag(PRIVATE)) + if (m.hasFlag(PRIVATE)) { m.resetFlag(PRIVATE | CASEACCESSOR).setFlag(PROTECTED) + } if (m.isConstructor) { val specCtor = enterMember(m.cloneSymbol(cls).setFlag(SPECIALIZED)) @@ -463,7 +464,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { def mkAccessor(field: Symbol, name: Name) = { val sym = cls.newMethod(field.pos, name) .setFlag(SPECIALIZED | m.getter(clazz).flags) - .resetFlag(LOCAL | PARAMACCESSOR | CASEACCESSOR) // we rely on the super class to initialize param accessors + .resetFlag(LOCAL | PARAMACCESSOR | CASEACCESSOR | LAZY) // we rely on the super class to initialize param accessors info(sym) = SpecializedAccessor(field) sym } @@ -471,7 +472,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { def overrideIn(clazz: Symbol, sym: Symbol) = { val sym1 = sym.cloneSymbol(clazz) .setFlag(OVERRIDE | SPECIALIZED) - .resetFlag(DEFERRED | CASEACCESSOR | ACCESSOR) + .resetFlag(DEFERRED | CASEACCESSOR | ACCESSOR | PARAMACCESSOR | LAZY) sym1.setInfo(sym1.info.asSeenFrom(clazz.tpe, sym1.owner)) } @@ -498,7 +499,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { log("found case field accessor for " + m + " added override " + cfaGetter); } - if (specVal.isVariable) { + if (specVal.isVariable && m.setter(clazz) != NoSymbol) { val specSetter = mkAccessor(specVal, nme.getterToSetter(specGetter.name)) .resetFlag(STABLE) specSetter.setInfo(MethodType(specSetter.newSyntheticValueParams(List(specVal.info)), @@ -612,7 +613,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { specMember.setInfo(subst(env, specMember.info)) .setFlag(SPECIALIZED) - .resetFlag(DEFERRED | CASEACCESSOR | ACCESSOR) + .resetFlag(DEFERRED | CASEACCESSOR | ACCESSOR | LAZY) } /** For each method m that overrides inherited method m', add a special @@ -662,7 +663,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { * It only allows binding of type parameters annotated with @specialized. * Fails if such an environment cannot be found. */ - private def unify(tp1: Type, tp2: Type, env: TypeEnv): TypeEnv = (tp1, tp2) match { + private def unify(tp1: Type, tp2: Type, env: TypeEnv): TypeEnv = { +// println("\tunify \t" + tp1 + "\n\t\t" + tp2) + (tp1, tp2) match { case (TypeRef(_, sym1, _), _) if sym1.hasAnnotation(SpecializedClass) => if (definitions.isValueType(tp2.typeSymbol)) env + ((sym1, tp2)) @@ -687,6 +690,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case (AnnotatedType(_, tp1, _), tp2) => unify(tp2, tp1, env) case (ExistentialType(_, res1), _) => unify(tp2, res1, env) } + } private def unify(tp1: List[Type], tp2: List[Type], env: TypeEnv): TypeEnv = tp1.zip(tp2).foldLeft(env) { (env, args) => @@ -867,21 +871,25 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val qual1 = transform(qual) specSym(qual1) match { case Some(specMember) => + log("found " + specMember) assert(symbol.info.typeParams.length == targs.length) val env = typeEnv(specMember) val residualTargs = for ((tvar, targ) <-symbol.info.typeParams.zip(targs) if !env.isDefinedAt(tvar)) yield targ assert(residualTargs.length == specMember.info.typeParams.length) - val tree1 = maybeTypeApply(Select(qual1, specMember.name), residualTargs) + val tree1 = maybeTypeApply(Select(qual1, specMember), residualTargs) log("rewrote " + tree + " to " + tree1) localTyper.typedOperator(atPos(tree.pos)(tree1)) // being polymorphic, it must be a method case None => super.transform(tree) } - case Select(qual, name) if (!specializedTypeVars(symbol.info).isEmpty && name != nme.CONSTRUCTOR) => + case Select(qual, name) if (!symbol.isMethod + && !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) val env = unify(symbol.tpe, tree.tpe, emptyEnv) log("checking for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe + " env: " + env) if (!env.isEmpty) { @@ -1066,9 +1074,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { */ override def traverse(tree: Tree): Unit = tree match { case Select(qual, name) => - if (tree.symbol.hasFlag(PRIVATE)) { + if (tree.symbol.hasFlag(PRIVATE | PROTECTED)) { log("changing private flag of " + tree.symbol) - tree.symbol.resetFlag(PRIVATE).setFlag(PROTECTED) +// tree.symbol.resetFlag(PRIVATE).setFlag(PROTECTED) + tree.symbol.resetFlag(PRIVATE | PROTECTED) } super.traverse(tree) -- cgit v1.2.3