diff --git a/effekt/shared/src/main/scala/effekt/source/ExplicitCapabilities.scala b/effekt/shared/src/main/scala/effekt/source/ExplicitCapabilities.scala index 3180352a5..1816ad48c 100644 --- a/effekt/shared/src/main/scala/effekt/source/ExplicitCapabilities.scala +++ b/effekt/shared/src/main/scala/effekt/source/ExplicitCapabilities.scala @@ -6,7 +6,6 @@ import effekt.symbols.* import effekt.context.assertions.* import effekt.source.Tree.Rewrite - /** * Transformation on source trees that translates programs into explicit capability-passing style * @@ -34,6 +33,9 @@ object ExplicitCapabilities extends Phase[Typechecked, Typechecked], Rewrite { val capabilities = Context.annotation(Annotations.BoundCapabilities, f) val capParams = capabilities.map(definitionFor) f.copy(bparams = bps ++ capParams, body = rewrite(body)) + case extDef @ ExternDef(capture, id, tparams, vparams, bparams, ret, bodies) => + val rewrittenBodies = bodies.map { rewrite } + extDef.copy(bodies = rewrittenBodies) } override def expr(using Context) = { @@ -127,6 +129,20 @@ object ExplicitCapabilities extends Phase[Typechecked, Typechecked], Rewrite { source.BlockLiteral(tps, vps, bps ++ capParams, rewrite(body)) } + override def rewrite(body: ExternBody)(using context.Context): ExternBody = + body match { + case b @ source.ExternBody.StringExternBody(ff, body) => + val rewrittenTemplate = + body.copy( + args = body.args.map { rewrite } + ) + b.copy(template = rewrittenTemplate) + case b @ source.ExternBody.EffektExternBody(ff, body) => + val rewrittenBody = rewrite(body) + b.copy(body = rewrittenBody) + case u: source.ExternBody.Unsupported => u + } + def referenceToCapability(capability: BlockParam)(using C: Context): Var = val id = IdRef(Nil, capability.name.name) C.assignSymbol(id, capability) diff --git a/examples/pos/extern-cap-passing.check b/examples/pos/extern-cap-passing.check new file mode 100644 index 000000000..baa224bfd --- /dev/null +++ b/examples/pos/extern-cap-passing.check @@ -0,0 +1 @@ +typechecks diff --git a/examples/pos/extern-cap-passing.effekt b/examples/pos/extern-cap-passing.effekt new file mode 100644 index 000000000..6ab64b232 --- /dev/null +++ b/examples/pos/extern-cap-passing.effekt @@ -0,0 +1,7 @@ +effect IOException(msg: String): Nothing +extern io def three: Nothing = + js "${box { (msg: String) => do IOException(msg) }}('oops')}" + +def main() = { + println("typechecks") +}