Skip to content

[rbi] Remove code that caused us to misidentify certain captured parameters as sending. #82427

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

gottesmm
Copy link
Contributor

Specifically, this code was added because otherwise we would in swift 5 + strict-concurrency mode emit two warnings, one at the AST level and one at the SIL level. Once we are in swift-6 mode, this does not happen since we stop compiling at the AST level since we will emit the AST level diagnostic as an error.

To do this, we tried to pattern match what the AST was erroring upon and treat the parameter as disconnected instead of being isolated. Sadly, this resulted in us treating certain closure cases incorrectly and not emit a diagnostic (creating a concurrency hole).

Given that this behavior results in a bad diagnostic only to avoid emitting two diagnostics in a mode which is not going to last forever... it really doesn't make sense to keep it. We really need a better way to handle these sorts of issues. Perhaps a special semantic parameter put on the function that squelches certain errors. But that is something for another day. The specific case it messes up is:

class NonSendable {
    func action() async {}
}

@MainActor
final class Foo {
    let value = NonSendable()

    func perform() {
        Task { [value] in
            await value.action() // Should emit error but do not.
        }
    }
}

In this case, we think that value is sending... when it isnt and we should emit an error.

rdar://146378329

@gottesmm gottesmm requested review from ktoso and eeckstein as code owners June 23, 2025 19:46
@gottesmm
Copy link
Contributor Author

@swift-ci smoke test

…meters as sending.

Specifically, this code was added because otherwise we would in swift 5 +
strict-concurrency mode emit two warnings, one at the AST level and one at the
SIL level. Once we are in swift-6 mode, this does not happen since we stop
compiling at the AST level since we will emit the AST level diagnostic as an
error.

To do this, we tried to pattern match what the AST was erroring upon and treat
the parameter as disconnected instead of being isolated. Sadly, this resulted in
us treating certain closure cases incorrectly and not emit a diagnostic
(creating a concurrency hole).

Given that this behavior results in a bad diagnostic only to avoid emitting two
diagnostics in a mode which is not going to last forever... it really doesn't
make sense to keep it. We really need a better way to handle these sorts of
issues. Perhaps a special semantic parameter put on the function that squelches
certain errors. But that is something for another day. The specific case it
messes up is:

```
class NonSendable {
    func action() async {}
}

@mainactor
final class Foo {
    let value = NonSendable()

    func perform() {
        Task { [value] in
            await value.action() // Should emit error but do not.
        }
    }
}
```

In this case, we think that value is sending... when it isnt and we should emit
an error.

rdar://146378329
@gottesmm gottesmm force-pushed the pr-9d8b2e21000560a9c3a3b0143c3fb3b22a0ca75a branch from 216bf0a to 865413d Compare June 23, 2025 19:49
@gottesmm
Copy link
Contributor Author

@swift-ci smoke test

@jamieQ
Copy link
Contributor

jamieQ commented Jun 24, 2025

for visibility, i believe the examples in each of:

will now produce diagnostics with this change

@gottesmm
Copy link
Contributor Author

@swift-ci smoke test linux platform

@gottesmm
Copy link
Contributor Author

@swift-ci test windows platform

@gottesmm
Copy link
Contributor Author

Going to look at the linux failures in a little bit

@CrystDragon
Copy link

CrystDragon commented Jul 4, 2025

@jamieQ Thanks for your information, and can you help verify if this PR can solve the following simple race? (The following code definitely contains a data race, but the compiler has no problem with it at the moment)

@MainActor
func test() {
    var s = 1
    Task { @MainActor  in
        for _ in 0..<100 {
            s += 1
        }
    }
    Task.detached {
        for _ in 0..<100 {
            s += 1
        }
    }
}

@jamieQ
Copy link
Contributor

jamieQ commented Jul 5, 2025

can you help verify if this PR can solve the following simple race?

@CrystDragon i looked into it in the past as i know you have a outstanding issue with this scenario, and checking again now with my local compiler checkout, this patch still does not resolve that problem. IIRC from looking into it a bit in the past, the problem is that the use after send diagnostics are generated, but then they are then getting suppressed for some reason.

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.

4 participants