How to debug or ensure single resume calls for continuations at compile time or with tools like Instruments?

When using the continuation API, we're required to call resume exactly once. While withCheckedContinuation helps catch runtime issues during debugging, I'm looking for ways to catch such errors at compile time or through tools like Instruments.

Is there any tool or technique that can help enforce or detect this requirement more strictly than runtime checks? Or would creating custom abstractions around Continuation be the only option to ensure safety? Any suggestions or best practices are appreciated.

Answered by DTS Engineer in 820921022
Written by sei-kim in 772228021
I'm looking for ways to catch such errors at compile time

There are two potential errors here:

  • Resuming twice

  • Not resuming at all

Regarding the first, you could, in theory, use a non-copyable wrapper to catch that at compile time. However, I’w not sure that would be worth the effort. I see this breaking down as follows:

  • For your wrapper to be effective, you have to remember to use it in all places.

  • However, doing that isn’t substantially easier than writing your continuation code correctly.

  • Unless your continuation code is super complex, in which case you might be better off refactoring that code so that it’s easy to confirm that the continuation is only called once.

But sure, give it a whirl, it sounds like a fun exercise. And you’re guaranteed to learn something, even if you don’t end up using the final result. A good place to start is WWDC 2024 Session 10170 Consume noncopyable types in Swift.

For the second, detecting that you’ve not resumed at all, I don’t see any way to do that at compile time. The issue is that all types are destructible, even non-copyable ones.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Written by sei-kim in 772228021
I'm looking for ways to catch such errors at compile time

There are two potential errors here:

  • Resuming twice

  • Not resuming at all

Regarding the first, you could, in theory, use a non-copyable wrapper to catch that at compile time. However, I’w not sure that would be worth the effort. I see this breaking down as follows:

  • For your wrapper to be effective, you have to remember to use it in all places.

  • However, doing that isn’t substantially easier than writing your continuation code correctly.

  • Unless your continuation code is super complex, in which case you might be better off refactoring that code so that it’s easy to confirm that the continuation is only called once.

But sure, give it a whirl, it sounds like a fun exercise. And you’re guaranteed to learn something, even if you don’t end up using the final result. A good place to start is WWDC 2024 Session 10170 Consume noncopyable types in Swift.

For the second, detecting that you’ve not resumed at all, I don’t see any way to do that at compile time. The issue is that all types are destructible, even non-copyable ones.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi Quinn,

Thank you for your detailed response and the recommendation to check out WWDC 2024 Session 10170. It clarified a lot about the challenges involved in handling continuations, especially detecting unresumed continuations at compile time.

To confirm my understanding: since there aren’t specific "Instruments" tools for this, the best approach would be to focus on writing continuation code carefully and rely on runtime checks to catch any errors. Would that be an accurate summary?

Thanks again for your insights and guidance!

How to debug or ensure single resume calls for continuations at compile time or with tools like Instruments?
 
 
Q