Skip to content

Conversation

rjmccall
Copy link
Contributor

@rjmccall rjmccall commented Sep 9, 2025

I was trying to just fix a bug where #isolation wasn't evaluated properly in closure expressions, but I realized that my fix had the potential to affect other cases, and my investigations revealed three other bugs:

  • The isolation computation for decl contexts was not recursively looking through defer scopes, so nested defer bodies were being treated as non-isolated.
  • The isolation computation for the hidden function containing the defer body did not look upwards at all, so defer bodies were not treated as being isolated the same way as their parent function. I think we might have compensated for this in a lot of ways, but #isolation could not possibly have evaluated correctly in caller-isolated contexts because the defer body simply didn't get the isolation passed to it.
  • Similarly, the isolation computation for default argument generators of nonisolated(nonsending) functions was never returning caller-isolated, so these functions were not receiving implicit isolation parameters or using them correctly.

I ended up going around in circles on the default-arguments bug a lot, and eventually I settled on implementing most of the structure necessary for fixing it but not actually fixing it. Changing the computation of the isolation should now just make everything in SILGen work.

The other bugs with closures and defer should all be fixed.

The first bug is that we weren't computing isolation correctly for
nested defers. This is an unlikely pattern of code, but it's good to fix.

The second bug is that getActorIsolationOfContext was looking through
defers, but getActorIsolation itself was not. This was causing defer
bodies to be emitted in SILGen without an isolation parameter, which
meant that #isolation could not possibly provide the right value. Fixing
this involves teaching SILGen that non-async functions can have
nonisolated(nonsending) isolation, but that's relatively straightforward.

This commit doesn't fix #isolation or adequately test SILGen, but that'll
be handled in a follow-up.
closures.

The fixes for initializers are just setting the stage for doing this
properly: we should be able to just change the isolation computation
in Sema and fix up the tests.
@rjmccall
Copy link
Contributor Author

rjmccall commented Sep 9, 2025

@swift-ci Please test

@rjmccall rjmccall merged commit e5b6a88 into swiftlang:main Sep 10, 2025
5 checks passed
@jamieQ
Copy link
Contributor

jamieQ commented Sep 10, 2025

oof, you're too fast @rjmccall – i tested locally and this variant appears to hit an issue in SILGen:

func isolated_defer(_ iso: isolated (any Actor)) {
    defer {
        _ = #isolation
    }
    do {}
}

would you expect this should have been handled by these changes?

@rjmccall
Copy link
Contributor Author

oof, you're too fast @rjmccall – i tested locally and this variant appears to hit an issue in SILGen:

func isolated_defer(_ iso: isolated (any Actor)) {
    defer {
        _ = #isolation
    }
    do {}
}

would you expect this should have been handled by these changes?

Ah, thanks for the test case. I can see how that would end up being handled differently within the compiler; I'll fix it.

@rjmccall
Copy link
Contributor Author

@jamieQ Should be fixed in #84206.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants