diff options
Diffstat (limited to 'src/continuations/plugin')
3 files changed, 129 insertions, 147 deletions
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala index 0ccba2cb80..ab1510bd7f 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala @@ -16,6 +16,13 @@ abstract class CPSAnnotationChecker extends CPSUtils { * Checks whether @cps annotations conform */ object checker extends AnnotationChecker { + private def addPlusMarker(tp: Type) = tp withAnnotation newPlusMarker() + private def addMinusMarker(tp: Type) = tp withAnnotation newMinusMarker() + + private def cleanPlus(tp: Type) = + removeAttribs(tp, MarkerCPSAdaptPlus, MarkerCPSTypes) + private def cleanPlusWith(tp: Type)(newAnnots: AnnotationInfo*) = + cleanPlus(tp) withAnnotations newAnnots.toList /** Check annotations to decide whether tpe1 <:< tpe2 */ def annotationsConform(tpe1: Type, tpe2: Type): Boolean = { @@ -27,78 +34,74 @@ abstract class CPSAnnotationChecker extends CPSUtils { if (tpe1.typeSymbol eq NothingClass) return true - val annots1 = filterAttribs(tpe1,MarkerCPSTypes) - val annots2 = filterAttribs(tpe2,MarkerCPSTypes) + val annots1 = cpsParamAnnotation(tpe1) + val annots2 = cpsParamAnnotation(tpe2) // @plus and @minus should only occur at the left, and never together // TODO: insert check - val adaptPlusAnnots1 = filterAttribs(tpe1,MarkerCPSAdaptPlus) - val adaptMinusAnnots1 = filterAttribs(tpe1,MarkerCPSAdaptMinus) // @minus @cps is the same as no annotations - if (!adaptMinusAnnots1.isEmpty) + if (hasMinusMarker(tpe1)) return annots2.isEmpty // to handle answer type modification, we must make @plus <:< @cps - if (!adaptPlusAnnots1.isEmpty && annots1.isEmpty) + if (hasPlusMarker(tpe1) && annots1.isEmpty) return true // @plus @cps will fall through and compare the @cps type args - // @cps parameters must match exactly - if ((annots1 corresponds annots2) { _.atp <:< _.atp }) - return true - - false + (annots1 corresponds annots2)(_.atp <:< _.atp) } - /** Refine the computed least upper bound of a list of types. * All this should do is add annotations. */ override def annotationsLub(tpe: Type, ts: List[Type]): Type = { if (!cpsEnabled) return tpe - val annots1 = filterAttribs(tpe, MarkerCPSTypes) - val annots2 = ts flatMap (filterAttribs(_, MarkerCPSTypes)) + val annots1 = cpsParamAnnotation(tpe) + val annots2 = ts flatMap cpsParamAnnotation if (annots2.nonEmpty) { - val cpsLub = AnnotationInfo(global.lub(annots1:::annots2 map (_.atp)), Nil, Nil) + val cpsLub = newMarker(global.lub(annots1:::annots2 map (_.atp))) val tpe1 = if (annots1.nonEmpty) removeAttribs(tpe, MarkerCPSTypes) else tpe tpe1.withAnnotation(cpsLub) - } else tpe + } + else tpe } /** Refine the bounds on type parameters to the given type arguments. */ override def adaptBoundsToAnnotations(bounds: List[TypeBounds], tparams: List[Symbol], targs: List[Type]): List[TypeBounds] = { if (!cpsEnabled) return bounds - val anyAtCPS = AnnotationInfo(appliedType(MarkerCPSTypes.tpe, List(NothingClass.tpe, AnyClass.tpe)), Nil, Nil) + val anyAtCPS = newCpsParamsMarker(NothingClass.tpe, AnyClass.tpe) + if (isFunctionType(tparams.head.owner.tpe) || tparams.head.owner == PartialFunctionClass) { vprintln("function bound: " + tparams.head.owner.tpe + "/"+bounds+"/"+targs) - if (targs.last.hasAnnotation(MarkerCPSTypes)) + if (hasCpsParamTypes(targs.last)) bounds.reverse match { - case res::b if !res.hi.hasAnnotation(MarkerCPSTypes) => + case res::b if !hasCpsParamTypes(res.hi) => (TypeBounds(res.lo, res.hi.withAnnotation(anyAtCPS))::b).reverse case _ => bounds } else bounds - } else if (tparams.head.owner == ByNameParamClass) { + } + else if (tparams.head.owner == ByNameParamClass) { vprintln("byname bound: " + tparams.head.owner.tpe + "/"+bounds+"/"+targs) - if (targs.head.hasAnnotation(MarkerCPSTypes) && !bounds.head.hi.hasAnnotation(MarkerCPSTypes)) - TypeBounds(bounds.head.lo, bounds.head.hi.withAnnotation(anyAtCPS))::Nil + val TypeBounds(lo, hi) = bounds.head + if (hasCpsParamTypes(targs.head) && !hasCpsParamTypes(hi)) + TypeBounds(lo, hi withAnnotation anyAtCPS) :: Nil else bounds } else bounds } - override def canAdaptAnnotations(tree: Tree, mode: Int, pt: Type): Boolean = { if (!cpsEnabled) return false vprintln("can adapt annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt) - val annots1 = filterAttribs(tree.tpe,MarkerCPSTypes) - val annots2 = filterAttribs(pt,MarkerCPSTypes) + val annots1 = cpsParamAnnotation(tree.tpe) + val annots2 = cpsParamAnnotation(pt) if ((mode & global.analyzer.PATTERNmode) != 0) { //println("can adapt pattern annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt) @@ -124,15 +127,14 @@ abstract class CPSAnnotationChecker extends CPSUtils { } */ if ((mode & global.analyzer.EXPRmode) != 0) { - if ((annots1 corresponds annots2) { case (a1,a2) => a1.atp <:< a2.atp }) { + if ((annots1 corresponds annots2)(_.atp <:< _.atp)) { vprintln("already same, can't adapt further") return false } if (annots1.isEmpty && !annots2.isEmpty && ((mode & global.analyzer.BYVALmode) == 0)) { //println("can adapt annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt) - val adapt = AnnotationInfo(MarkerCPSAdaptPlus.tpe, Nil, Nil) - if (!tree.tpe.annotations.contains(adapt)) { + if (!hasPlusMarker(tree.tpe)) { // val base = tree.tpe <:< removeAllCPSAnnotations(pt) // val known = global.analyzer.isFullyDefined(pt) // println(same + "/" + base + "/" + known) @@ -144,7 +146,7 @@ abstract class CPSAnnotationChecker extends CPSUtils { //} } } else if (!annots1.isEmpty && ((mode & global.analyzer.BYVALmode) != 0)) { - if (!tree.tpe.hasAnnotation(MarkerCPSAdaptMinus)) { + if (!hasMinusMarker(tree.tpe)) { vprintln("yes we can!! (byval)") return true } @@ -153,18 +155,17 @@ abstract class CPSAnnotationChecker extends CPSUtils { false } - override def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = { if (!cpsEnabled) return tree vprintln("adapt annotations " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt) - val annots1 = filterAttribs(tree.tpe,MarkerCPSTypes) - val annots2 = filterAttribs(pt,MarkerCPSTypes) + val annots1 = cpsParamAnnotation(tree.tpe) + val annots2 = cpsParamAnnotation(pt) if ((mode & global.analyzer.PATTERNmode) != 0) { if (!annots1.isEmpty) { - return tree.setType(removeAllCPSAnnotations(tree.tpe)) + return tree modifyType removeAllCPSAnnotations } } @@ -185,8 +186,6 @@ abstract class CPSAnnotationChecker extends CPSUtils { // add a marker annotation that will make tree.tpe behave as pt, subtyping wise // tree will look like having any possible annotation //println("adapt annotations " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt) - - val adapt = AnnotationInfo(MarkerCPSAdaptPlus.tpe, Nil, Nil) //val same = annots2 forall { case AnnotationInfo(atp: TypeRef, _, _) => atp.typeArgs(0) =:= atp.typeArgs(1) } // TBD: use same or not? see infer0.scala/infer1.scala @@ -196,9 +195,9 @@ abstract class CPSAnnotationChecker extends CPSUtils { //val known = global.analyzer.isFullyDefined(pt) - if (/*same &&*/ !tree.tpe.annotations.contains(adapt)) { + if (/*same &&*/ !hasPlusMarker(tree.tpe)) { //if (known) - return tree.setType(tree.tpe.withAnnotations(adapt::annots2)) // needed for #1807 + return tree modifyType (_ withAnnotations newPlusMarker() :: annots2) // needed for #1807 //else // return tree.setType(tree.tpe.withAnnotations(adapt::Nil)) } @@ -206,16 +205,14 @@ abstract class CPSAnnotationChecker extends CPSUtils { } else if (!annots1.isEmpty && ((mode & global.analyzer.BYVALmode) != 0)) { // dropping annotation // add a marker annotation that will make tree.tpe behave as pt, subtyping wise // tree will look like having no annotation - if (!tree.tpe.hasAnnotation(MarkerCPSAdaptMinus)) { - val adapt = AnnotationInfo(MarkerCPSAdaptMinus.tpe, Nil, Nil) - return tree.setType(tree.tpe.withAnnotations(adapt::Nil)) + if (!hasMinusMarker(tree.tpe)) { + return tree modifyType addMinusMarker } } } tree } - def updateAttributesFromChildren(tpe: Type, childAnnots: List[AnnotationInfo], byName: List[Tree]): Type = { tpe match { // Would need to push annots into each alternative of overloaded type @@ -226,7 +223,7 @@ abstract class CPSAnnotationChecker extends CPSUtils { OverloadedType(pre, alts.map((sym: Symbol) => updateAttributes(pre.memberType(sym), annots))) */ case _ => - assert(childAnnots forall (_.atp.typeSymbol == MarkerCPSTypes), childAnnots) + assert(childAnnots forall (_ matches MarkerCPSTypes), childAnnots) /* [] + [] = [] plus + [] = plus @@ -243,56 +240,50 @@ abstract class CPSAnnotationChecker extends CPSUtils { synth cps + cps = synth cps! <- unify */ - val plus = tpe.hasAnnotation(MarkerCPSAdaptPlus) || (tpe.hasAnnotation(MarkerCPSTypes) && - byName.nonEmpty && byName.forall(_.tpe.hasAnnotation(MarkerCPSAdaptPlus))) + val plus = hasPlusMarker(tpe) || ( + hasCpsParamTypes(tpe) + && byName.nonEmpty + && (byName forall (t => hasPlusMarker(t.tpe))) + ) // move @plus annotations outward from by-name children - if (childAnnots.isEmpty) { + if (childAnnots.isEmpty) return { if (plus) { // @plus or @plus @cps - for (t <- byName) { - //println("removeAnnotation " + t + " / " + t.tpe) - t.setType(removeAttribs(t.tpe, MarkerCPSAdaptPlus, MarkerCPSTypes)) - } - return tpe.withAnnotation(AnnotationInfo(MarkerCPSAdaptPlus.tpe, Nil, Nil)) - } else - return tpe + byName foreach (_ modifyType cleanPlus) + addPlusMarker(tpe) + } + else tpe } - val annots1 = filterAttribs(tpe, MarkerCPSTypes) + val annots1 = cpsParamAnnotation(tpe) if (annots1.isEmpty) { // nothing or @plus - val synth = MarkerCPSSynth.tpe - val annots2 = List(linearize(childAnnots)) - removeAttribs(tpe,MarkerCPSAdaptPlus).withAnnotations(AnnotationInfo(synth, Nil, Nil)::annots2) - } else { + cleanPlusWith(tpe)(newSynthMarker(), linearize(childAnnots)) + } + else { val annot1 = single(annots1) if (plus) { // @plus @cps - val synth = AnnotationInfo(MarkerCPSSynth.tpe, Nil, Nil) val annot2 = linearize(childAnnots) - if (!(annot2.atp <:< annot1.atp)) - throw new TypeError(annot2 + " is not a subtype of " + annot1) - val res = removeAttribs(tpe, MarkerCPSAdaptPlus, MarkerCPSTypes).withAnnotations(List(synth, annot2)) - for (t <- byName) { - //println("removeAnnotation " + t + " / " + t.tpe) - t.setType(removeAttribs(t.tpe, MarkerCPSAdaptPlus, MarkerCPSTypes)) + + if (annot2.atp <:< annot1.atp) { + try cleanPlusWith(tpe)(newSynthMarker(), annot2) + finally byName foreach (_ modifyType cleanPlus) } - res - } else if (tpe.hasAnnotation(MarkerCPSSynth)) { // @synth @cps + else throw new TypeError(annot2 + " is not a subtype of " + annot1) + } + else if (hasSynthMarker(tpe)) { // @synth @cps val annot2 = linearize(childAnnots) - if (!(annot2.atp <:< annot1.atp)) + if (annot2.atp <:< annot1.atp) + cleanPlusWith(tpe)(annot2) + else throw new TypeError(annot2 + " is not a subtype of " + annot1) - removeAttribs(tpe, MarkerCPSTypes).withAnnotation(annot2) - } else { // @cps - removeAttribs(tpe, MarkerCPSTypes).withAnnotation(linearize(childAnnots:::annots1)) } + else // @cps + cleanPlusWith(tpe)(linearize(childAnnots:::annots1)) } } } - - - - def transArgList(fun: Tree, args: List[Tree]): List[List[Tree]] = { val formals = fun.tpe.paramTypes val overshoot = args.length - formals.length @@ -329,7 +320,7 @@ abstract class CPSAnnotationChecker extends CPSUtils { def transChildrenInOrder(tree: Tree, tpe: Type, childTrees: List[Tree], byName: List[Tree]) = { val children = childTrees.flatMap { t => if (t.tpe eq null) Nil else { - val types = filterAttribs(t.tpe, MarkerCPSTypes) + val types = cpsParamAnnotation(t.tpe) // TODO: check that it has been adapted and if so correctly if (types.isEmpty) Nil else List(single(types)) } @@ -348,7 +339,7 @@ abstract class CPSAnnotationChecker extends CPSUtils { override def addAnnotations(tree: Tree, tpe: Type): Type = { if (!cpsEnabled) { - if (tpe.annotations.nonEmpty && tpe.hasAnnotation(MarkerCPSTypes)) + if (hasCpsParamTypes(tpe)) global.reporter.error(tree.pos, "this code must be compiled with the Scala continuations plugin enabled") return tpe } @@ -397,7 +388,7 @@ abstract class CPSAnnotationChecker extends CPSUtils { // we cannot safely annotate these. so we just ignore these cases and // clean up later in the Apply/TypeApply trees. - if (qual.tpe.hasAnnotation(MarkerCPSTypes)) { + if (hasCpsParamTypes(qual.tpe)) { // however there is one special case: // if it's a method without parameters, just apply it. normally done in adapt, but // we have to do it here so we don't lose the cps information (wouldn't trigger our @@ -425,10 +416,10 @@ abstract class CPSAnnotationChecker extends CPSUtils { case Try(block, catches, finalizer) => val tpe1 = transChildrenInOrder(tree, tpe, Nil, block::catches:::(catches collect { case CaseDef(_, _, body) => body })) - val annots = filterAttribs(tpe1, MarkerCPSTypes) + val annots = cpsParamAnnotation(tpe1) if (annots.nonEmpty) { val ann = single(annots) - val atp0::atp1::Nil = ann.atp.normalize.typeArgs + val (atp0, atp1) = annTypes(ann) if (!(atp0 =:= atp1)) throw new TypeError("only simple cps types allowed in try/catch blocks (found: " + tpe1 + ")") if (!finalizer.isEmpty) // no finalizers allowed. see explanation in SelectiveCPSTransform @@ -445,8 +436,8 @@ abstract class CPSAnnotationChecker extends CPSUtils { // ValDef symbols must *not* have annotations! if (hasAnswerTypeAnn(tree.symbol.info)) { // is it okay to modify sym here? vprintln("removing annotation from sym " + tree.symbol + "/" + tree.symbol.tpe + "/" + tpt) - tpt.setType(removeAllCPSAnnotations(tpt.tpe)) - tree.symbol.setInfo(removeAllCPSAnnotations(tree.symbol.info)) + tpt modifyType removeAllCPSAnnotations + tree.symbol modifyInfo removeAllCPSAnnotations } tpe diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala index d1a35df04b..5cb06d42db 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala @@ -13,96 +13,90 @@ trait CPSUtils { val verbose: Boolean = System.getProperty("cpsVerbose", "false") == "true" def vprintln(x: =>Any): Unit = if (verbose) println(x) - lazy val MarkerCPSSym = definitions.getClass("scala.util.continuations.cpsSym") - lazy val MarkerCPSTypes = definitions.getClass("scala.util.continuations.cpsParam") - lazy val MarkerCPSSynth = definitions.getClass("scala.util.continuations.cpsSynth") - - lazy val MarkerCPSAdaptPlus = definitions.getClass("scala.util.continuations.cpsPlus") + lazy val MarkerCPSSym = definitions.getClass("scala.util.continuations.cpsSym") + lazy val MarkerCPSTypes = definitions.getClass("scala.util.continuations.cpsParam") + lazy val MarkerCPSSynth = definitions.getClass("scala.util.continuations.cpsSynth") + lazy val MarkerCPSAdaptPlus = definitions.getClass("scala.util.continuations.cpsPlus") lazy val MarkerCPSAdaptMinus = definitions.getClass("scala.util.continuations.cpsMinus") - lazy val Context = definitions.getClass("scala.util.continuations.ControlContext") - lazy val ModCPS = definitions.getModule("scala.util.continuations") - lazy val MethShiftUnit = definitions.getMember(ModCPS, "shiftUnit") - lazy val MethShiftUnitR = definitions.getMember(ModCPS, "shiftUnitR") - lazy val MethShift = definitions.getMember(ModCPS, "shift") - lazy val MethShiftR = definitions.getMember(ModCPS, "shiftR") - lazy val MethReify = definitions.getMember(ModCPS, "reify") - lazy val MethReifyR = definitions.getMember(ModCPS, "reifyR") + lazy val MethShiftUnit = definitions.getMember(ModCPS, "shiftUnit") + lazy val MethShiftUnitR = definitions.getMember(ModCPS, "shiftUnitR") + lazy val MethShift = definitions.getMember(ModCPS, "shift") + lazy val MethShiftR = definitions.getMember(ModCPS, "shiftR") + lazy val MethReify = definitions.getMember(ModCPS, "reify") + lazy val MethReifyR = definitions.getMember(ModCPS, "reifyR") lazy val allCPSAnnotations = List(MarkerCPSSym, MarkerCPSTypes, MarkerCPSSynth, MarkerCPSAdaptPlus, MarkerCPSAdaptMinus) + // TODO - needed? Can these all use the same annotation info? + protected def newSynthMarker() = newMarker(MarkerCPSSynth) + protected def newPlusMarker() = newMarker(MarkerCPSAdaptPlus) + protected def newMinusMarker() = newMarker(MarkerCPSAdaptMinus) + protected def newMarker(tpe: Type): AnnotationInfo = AnnotationInfo marker tpe + protected def newMarker(sym: Symbol): AnnotationInfo = AnnotationInfo marker sym.tpe + + protected def newCpsParamsMarker(tp1: Type, tp2: Type) = + newMarker(appliedType(MarkerCPSTypes.tpe, List(tp1, tp2))) + // annotation checker + protected def annTypes(ann: AnnotationInfo): (Type, Type) = { + val tp0 :: tp1 :: Nil = ann.atp.normalize.typeArgs + ((tp0, tp1)) + } + protected def hasMinusMarker(tpe: Type) = tpe hasAnnotation MarkerCPSAdaptMinus + protected def hasPlusMarker(tpe: Type) = tpe hasAnnotation MarkerCPSAdaptPlus + protected def hasSynthMarker(tpe: Type) = tpe hasAnnotation MarkerCPSSynth + protected def hasCpsParamTypes(tpe: Type) = tpe hasAnnotation MarkerCPSTypes + protected def cpsParamTypes(tpe: Type) = tpe getAnnotation MarkerCPSTypes map annTypes + def filterAttribs(tpe:Type, cls:Symbol) = - tpe.annotations.filter(_.atp.typeSymbol == cls) + tpe.annotations filter (_ matches cls) - def removeAttribs(tpe:Type, cls:Symbol*) = - tpe.withoutAnnotations.withAnnotations(tpe.annotations.filterNot(cls contains _.atp.typeSymbol)) + def removeAttribs(tpe: Type, classes: Symbol*) = + tpe filterAnnotations (ann => !(classes exists (ann matches _))) def removeAllCPSAnnotations(tpe: Type) = removeAttribs(tpe, allCPSAnnotations:_*) + def cpsParamAnnotation(tpe: Type) = filterAttribs(tpe, MarkerCPSTypes) + def linearize(ann: List[AnnotationInfo]): AnnotationInfo = { - ann.reduceLeft { (a, b) => - val atp0::atp1::Nil = a.atp.normalize.typeArgs - val btp0::btp1::Nil = b.atp.normalize.typeArgs - val (u0,v0) = (atp0, atp1) - val (u1,v1) = (btp0, btp1) -/* - val (u0,v0) = (a.atp.typeArgs(0), a.atp.typeArgs(1)) - val (u1,v1) = (b.atp.typeArgs(0), b.atp.typeArgs(1)) - vprintln("check lin " + a + " andThen " + b) -*/ - vprintln("check lin " + a + " andThen " + b) - if (!(v1 <:< u0)) + ann reduceLeft { (a, b) => + val (u0,v0) = annTypes(a) + val (u1,v1) = annTypes(b) + // vprintln("check lin " + a + " andThen " + b) + + if (v1 <:< u0) + newCpsParamsMarker(u1, v0) + else throw new TypeError("illegal answer type modification: " + a + " andThen " + b) - // TODO: improve error message (but it is not very common) - AnnotationInfo(appliedType(MarkerCPSTypes.tpe, List(u1,v0)),Nil,Nil) } } // anf transform def getExternalAnswerTypeAnn(tp: Type) = { - tp.annotations.find(a => a.atp.typeSymbol == MarkerCPSTypes) match { - case Some(AnnotationInfo(atp, _, _)) => - val atp0::atp1::Nil = atp.normalize.typeArgs - Some((atp0, atp1)) - case None => - if (tp.hasAnnotation(MarkerCPSAdaptPlus)) - global.warning("trying to instantiate type " + tp + " to unknown cps type") - None - } - } - - def getAnswerTypeAnn(tp: Type) = { - tp.annotations.find(a => a.atp.typeSymbol == MarkerCPSTypes) match { - case Some(AnnotationInfo(atp, _, _)) => - if (!tp.hasAnnotation(MarkerCPSAdaptPlus)) {//&& !tp.hasAnnotation(MarkerCPSAdaptMinus)) - val atp0::atp1::Nil = atp.normalize.typeArgs - Some((atp0, atp1)) - } else - None - case None => None + cpsParamTypes(tp) orElse { + if (hasPlusMarker(tp)) + global.warning("trying to instantiate type " + tp + " to unknown cps type") + None } } - def hasAnswerTypeAnn(tp: Type) = { - tp.hasAnnotation(MarkerCPSTypes) && !tp.hasAnnotation(MarkerCPSAdaptPlus) /*&& - !tp.hasAnnotation(MarkerCPSAdaptMinus)*/ - } + def getAnswerTypeAnn(tp: Type): Option[(Type, Type)] = + cpsParamTypes(tp) filterNot (_ => hasPlusMarker(tp)) - def hasSynthAnn(tp: Type) = { - tp.annotations.exists(a => a.atp.typeSymbol == MarkerCPSSynth) - } + def hasAnswerTypeAnn(tp: Type) = + hasCpsParamTypes(tp) && !hasPlusMarker(tp) def updateSynthFlag(tree: Tree) = { // remove annotations if *we* added them (@synth present) - if (hasSynthAnn(tree.tpe)) { + if (hasSynthMarker(tree.tpe)) { log("removing annotation from " + tree) - tree.setType(removeAllCPSAnnotations(tree.tpe)) + tree modifyType removeAllCPSAnnotations } else tree } @@ -124,7 +118,4 @@ trait CPSUtils { case _ => None } } - - // cps transform - -}
\ No newline at end of file +} diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala index 8889b75770..9f1d3dfcd6 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala @@ -301,7 +301,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with log("cps type conversion (has: " + cpsA + "/" + spc + "/" + expr.tpe + ")") log("cps type conversion (expected: " + cpsR.get + "): " + expr) - if (!expr.tpe.hasAnnotation(MarkerCPSAdaptPlus)) + if (!hasPlusMarker(expr.tpe)) unit.warning(tree.pos, "expression " + tree + " is cps-transformed unexpectedly") try { @@ -331,9 +331,9 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with } else { // all is well - if (expr.tpe.hasAnnotation(MarkerCPSAdaptPlus)) { + if (hasPlusMarker(expr.tpe)) { unit.warning(tree.pos, "expression " + expr + " of type " + expr.tpe + " is not expected to have a cps type") - expr.setType(removeAllCPSAnnotations(expr.tpe)) + expr modifyType removeAllCPSAnnotations } // TODO: sanity check that types agree |