diff --git a/effekt/shared/src/main/scala/effekt/Typer.scala b/effekt/shared/src/main/scala/effekt/Typer.scala index ef161e147..77558ef38 100644 --- a/effekt/shared/src/main/scala/effekt/Typer.scala +++ b/effekt/shared/src/main/scala/effekt/Typer.scala @@ -1198,10 +1198,10 @@ object Typer extends Phase[NameResolved, Typechecked] { Context.abort(s"Wrong number of type arguments, given ${targs.size}, but ${name} expects ${funTpe.tparams.size}.") if (vargs.size != funTpe.vparams.size) - Context.error(s"Wrong number of value arguments, given ${vargs.size}, but ${name} expects ${funTpe.vparams.size}.") + Context.abort(s"Wrong number of value arguments, given ${vargs.size}, but ${name} expects ${funTpe.vparams.size}.") if (bargs.size != funTpe.bparams.size) - Context.error(s"Wrong number of block arguments, given ${bargs.size}, but ${name} expects ${funTpe.bparams.size}.") + Context.abort(s"Wrong number of block arguments, given ${bargs.size}, but ${name} expects ${funTpe.bparams.size}.") val callsite = currentCapture @@ -1222,7 +1222,16 @@ object Typer extends Phase[NameResolved, Typechecked] { effs = effs ++ eff } - (bps zip bargs zip captArgs) foreach { case ((tpe, expr), capt) => + // To improve inference, we first type check block arguments that DO NOT subtract effects, + // since those need to be fully known. + + val (withoutEffects, withEffects) = (bps zip (bargs zip captArgs)).partitionMap { + // TODO refine and check that eff.args refers to (inferred) type arguments of this application (`typeArgs`) + case (tpe : FunctionType, rest) if tpe.effects.exists { eff => eff.args.nonEmpty } => Right((tpe, rest)) + case (tpe, rest) => Left((tpe, rest)) + } + + (withoutEffects ++ withEffects) foreach { case (tpe, (expr, capt)) => flowsInto(capt, callsite) // capture of block <: ?C flowingInto(capt) { diff --git a/examples/pos/issue661.check b/examples/pos/issue661.check new file mode 100644 index 000000000..dcf37cd5e --- /dev/null +++ b/examples/pos/issue661.check @@ -0,0 +1,3 @@ +2 +3 +4 diff --git a/examples/pos/issue661.effekt b/examples/pos/issue661.effekt new file mode 100644 index 000000000..961158e4e --- /dev/null +++ b/examples/pos/issue661.effekt @@ -0,0 +1,21 @@ +interface Iter[T] { + def yield(value: T): Unit +} + +def iter[T](self: List[T]): Unit / {Iter[T]} = + self match { + case Cons(head, tail) => do yield(head); iter(tail) + case Nil() => () + } + +def my_map[T, U] {action: () => Unit / {Iter[T]}} {f: T => U}: Unit / {Iter[U]} = + try action() + with Iter[T] { + def yield(value) = { do yield(f(value)); resume(()) } + } + +def main() = + try my_map { iter([1, 2, 3]) } { x => x+1 } + with Iter[Int] { + def yield(x) = { println(x); resume(()) } + } \ No newline at end of file