Skip to content

Make overloads and witnesses permit @Sendable variance #42194

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

Merged

Conversation

beccadax
Copy link
Contributor

@beccadax beccadax commented Apr 5, 2022

For both overloaded methods and protocol witnesses, this PR:

  • Allows a non-@Sendable function type in the override/witness's parameters to match an @Sendable function type in the base/requirement.
  • Allows an @Sendable function type in the override/witness's results to match a non-@Sendable function type in the base/requirement.
  • Specially diagnoses any other difference in sendability, and reduces it to a warning in Swift 5 mode.

We'd like these warnings to also go away when @preconcurrency is used, but this seems like a reasonable stopping point.

Fixes rdar://91109455.

beccadax added 3 commits April 5, 2022 13:50
Specifically, an override can validly have a parameter type that is not `@Sendable` or a function type that is `@Sendable` even if that contradicts the base declaration. That’s becuase it’s always valid to provide a sendable function when one is not actually needed, but not vice versa.
It previously treated parameters and return types as the same, instead of properly handling variance.
@beccadax beccadax marked this pull request as draft April 5, 2022 21:03
Comment on lines +1167 to +1172
/// If the *only* problems are that `@Sendable` attributes are missing,
/// allow the match in some circumstances.
requiresNonSendable = solution
&& llvm::all_of(solution->Fixes, [](constraints::ConstraintFix *fix) {
return fix->getKind() == constraints::FixKind::AddSendableAttribute;
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bit seems a little questionable—I'd like reviewers to let me know if they think it'll work as intended.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will work. I do wonder if we need to do a similar thing for global-actor-qualified function parameters (although I suspect they'll be much more rare).

@beccadax beccadax force-pushed the witness-accounts-are-only-approximate branch from 46dae55 to 4ab5233 Compare April 5, 2022 23:47
@beccadax beccadax marked this pull request as ready for review April 6, 2022 00:50
@beccadax
Copy link
Contributor Author

beccadax commented Apr 6, 2022

@swift-ci please smoke test

@beccadax beccadax requested a review from DougGregor April 6, 2022 00:50
Copy link
Member

@DougGregor DougGregor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fantastic! Thank you.

// Removing '@Sendable' is ABI-compatible because there's nothing wrong with
// a function being sendable when it doesn't need to be.
if (!ext2.isSendable())
ext1 = ext1.withConcurrent(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, good catch here.

// FIXME: suppress if any matches brought in via @preconcurrency import?
diags.diagnose(decl, diag::override_sendability_mismatch,
decl->getName())
.warnUntilSwiftVersion(6);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where we would do the @preconcurrency check, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

// FIXME: suppress if any matches brought in via @preconcurrency import?
diags.diagnose(decl, diag::override_sendability_mismatch,
decl->getName())
.warnUntilSwiftVersion(6);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... and here, for @preconcurrency checks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And yes.

Comment on lines +1167 to +1172
/// If the *only* problems are that `@Sendable` attributes are missing,
/// allow the match in some circumstances.
requiresNonSendable = solution
&& llvm::all_of(solution->Fixes, [](constraints::ConstraintFix *fix) {
return fix->getKind() == constraints::FixKind::AddSendableAttribute;
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will work. I do wonder if we need to do a similar thing for global-actor-qualified function parameters (although I suspect they'll be much more rare).

@beccadax
Copy link
Contributor Author

beccadax commented Apr 7, 2022

@swift-ci smoke test and merge

@beccadax
Copy link
Contributor Author

beccadax commented Apr 7, 2022

Flaky test?

@swift-ci please smoke test macOS platform

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