diff options
Diffstat (limited to 'src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala')
-rw-r--r-- | src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala index cde602bf83..249ae565cc 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala @@ -224,16 +224,32 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes { res } else if (retMode && !hasPlusMarker(tree.tpe) && annotsTree.isEmpty && annotsExpected.nonEmpty) { // add a marker annotation that will make tree.tpe behave as pt, subtyping wise - // tree will look like having no annotation + // tree will look like having any possible annotation - // note that we are only adding a plus marker if the method's result type is a CPS type - // (annotsExpected.nonEmpty == cpsParamAnnotation(pt).nonEmpty) + // note 1: we are only adding a plus marker if the method's result type is a cps type + // (annotsExpected.nonEmpty == cpsParamAnnotation(pt).nonEmpty) + // note 2: we are not adding the expected cps annotations, since they will be added + // by adaptTypeOfReturn (see below). val res = tree modifyType (_ withAnnotations List(newPlusMarker())) vprintln("adapted annotations (return) of " + tree + " to " + res.tpe) res } else tree } + // only adapt type if this return will + // (a) be removed (in tail position and method's result type (pt) is cps type), or + // (b) cause an error + override def adaptTypeOfReturn(tree: Tree, pt: Type, default: => Type): Type = { + // only adapt if method's result type (pt) is cps type + val annots = cpsParamAnnotation(pt) + if (annots.nonEmpty) { + // return type of `tree` without plus marker, but only if it doesn't have other cps annots + if (hasPlusMarker(tree.tpe) && !hasCpsParamTypes(tree.tpe)) + tree.setType(removeAttribs(tree.tpe, MarkerCPSAdaptPlus)) + tree.tpe + } else default + } + def updateAttributesFromChildren(tpe: Type, childAnnots: List[AnnotationInfo], byName: List[Tree]): Type = { tpe match { // Would need to push annots into each alternative of overloaded type @@ -486,13 +502,6 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes { } tpe - case ret @ Return(expr) => - // only change type if this return will (a) be removed (in tail position) or (b) cause - // an error (not in tail position) - if (expr.tpe != null && hasPlusMarker(expr.tpe)) - ret setType expr.tpe - ret.tpe - case _ => tpe } |