Skip to content

[cxx-interop] allow shared ref retain function to return self #77837

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
merged 2 commits into from
Dec 5, 2024

Conversation

lhoward
Copy link
Contributor

@lhoward lhoward commented Nov 26, 2024

Many existing C APIs for retaining references, including Apple's own, return the reference. Support this pattern, along with the existing void return signature, with when importing reference types from C++.

More: https://forums.swift.org/t/swift-shared-reference-signature-error/76194/7

@lhoward
Copy link
Contributor Author

lhoward commented Nov 26, 2024

Note to self: need separate error message for invalid retain return value.

@lhoward lhoward force-pushed the lhoward/retain-return-self branch from c077f57 to 85ea760 Compare November 26, 2024 01:15
@lhoward lhoward force-pushed the lhoward/retain-return-self branch 2 times, most recently from d9903f1 to 46c2da4 Compare November 27, 2024 06:56
@lhoward
Copy link
Contributor Author

lhoward commented Nov 27, 2024

Tests are now failing, investigating.

@lhoward lhoward force-pushed the lhoward/retain-return-self branch from 46c2da4 to 8d56f5a Compare November 27, 2024 21:16
@lhoward
Copy link
Contributor Author

lhoward commented Nov 27, 2024

Tests passing again.

@egorzhdan egorzhdan added the c++ interop Feature: Interoperability with C++ label Nov 28, 2024
@zoecarver
Copy link
Contributor

LGTM

@lhoward
Copy link
Contributor Author

lhoward commented Nov 28, 2024

Just double checking we don't need to do anything extra at the retain call site to ignore the return value.

auto resultInterfaceType = operationFn->getResultInterfaceType();
if (!resultInterfaceType->isVoid()) {
if (operationKind == CustomRefCountingOperationKind::release ||
resultInterfaceType->getAnyNominal() != paramDecl)
Copy link
Member

Choose a reason for hiding this comment

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

This check isn't correct: it's comparing the declaration result's nominal type (if there is one) against the parameter declaration itself (which has, e.g., the name of the parameter in it). Instead, you need to compare the result type against the parameter type. I also expect that we need to look through an optional type on the result type, in case the retain function handles null pointers in some manner. Specifically, I think it should be:

Suggested change
resultInterfaceType->getAnyNominal() != paramDecl)
!resultInterfaceType->lookThroughSingleOptionalType()->isEqual(paramType))

Copy link
Member

Choose a reason for hiding this comment

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

I'm confused about why this PR worked without this change suggested above. Running tests in CI without the change because I would expect it to fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fix applied (shouldn't disrupt running builds to check previous commit).

@@ -2534,24 +2534,23 @@ namespace {
void validateForeignReferenceType(const clang::CXXRecordDecl *decl,
ClassDecl *classDecl) {

enum class RetainReleaseOperatonKind {
enum class RetainReleaseOperationKind {
Copy link
Member

Choose a reason for hiding this comment

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

Ah, thank you for the typo fix here!

@DougGregor
Copy link
Member

@swift-ci please smoke test macOS

Many existing C APIs for retaining references, including Apple's own, return
the reference. Support this pattern, along with the existing void return
signature, with when importing reference types from C++.
@lhoward lhoward force-pushed the lhoward/retain-return-self branch from 8d56f5a to da23bcf Compare December 3, 2024 01:09
@DougGregor
Copy link
Member

@swift-ci please smoke test

@lhoward
Copy link
Contributor Author

lhoward commented Dec 3, 2024

What's the next release one might expect to see this in?

@DougGregor
Copy link
Member

Once it's merged to main, we can cherry-pick to the release/6.1 branch for the 6.1 release (Q1 2025)

@finagolfin
Copy link
Member

@swift-ci please smoke test

Copy link
Contributor

@egorzhdan egorzhdan left a comment

Choose a reason for hiding this comment

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

This seems very reasonable, LGTM, thank you!

@DougGregor
Copy link
Member

@swift-ci please smoke test Linux

@DougGregor
Copy link
Member

@lhoward I'm going to merge now. Would you cherry-pick this to the release/6.1 branch? There are instructions at https://forums.swift.org/t/swift-6-1-release-process/75442#p-344524-pull-requests-for-release-branch-8

@DougGregor DougGregor merged commit 41073a8 into swiftlang:main Dec 5, 2024
3 checks passed
@lhoward
Copy link
Contributor Author

lhoward commented Feb 12, 2025

Retain functions that return self need to be manually annotated with SWIFT_RETURNS_RETAINED. Perhaps this could be inferred in a future patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ interop Feature: Interoperability with C++
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants