[Accepted] SE-0377 (revision): Make `borrowing` and `consuming` parameters require explicit copying with the `copy` operator

Hello, Swift community. The review of the revision of SE-0377 ran from May 15th through the 29th. This review was narrowly focused on a specific revision of the proposal, discussed in the review thread linked above. Feedback on this revision was strongly positive.

One question did arise during the review about the interaction with initializer parameters. Initializer parameters have long been special in the Swift ABI because they default to consuming, whereas other parameters default to borrowing. Prior to this revision, this fact was interesting to people focused on performance or ABI stability, but it had no direct impact on the language. This revision changes that because passing an explicitly-modified parameter to an initializer has different implications than passing it to any other function: passing an explicitly borrowing parameter to an initializer is invalid without a copy, and passing an explicitly consuming parameter to an initializer consumes it, making any further uses invalid. The question is whether it is acceptable to raise this ABI detail into the language.

The Language Steering Group believes that, on balance, raising this detail into the language is the best thing to do. There are alternatives: for example, we could allow callers to implicitly copy into initializer parameters, thus hiding any difference between the parameters of initializers and other functions. However, that would greatly damage this feature as a reliable local optimization, since a programmer could end up with implicit copies even when everything was fully annotated. We also wouldn't want to use the presence of an explicit modifier on a parameter to enable stronger diagnostics in the caller, since that would give these modifiers non-local impact, making them much harder to adopt in real code. The Language Steering Group sees the use of these modifiers on copyable types as a feature mostly for advanced users, and we believe it's acceptable to expect such users to understand things like the default convention being different for initializers. Therefore, we are comfortable with the design of this feature laid out in the revised proposal.

Accordingly, the revision to SE-0377 is accepted.

Thank you all for your contributions to this review.

John McCall
Review Manager

24 Likes

Right now the proposal states that it's implemented in Swift 5.9 but without the no-implicit-copy constraint. Will the no-implicit-copy constraint be added to the implementation as well before Swift 5.9 is released?

As currently implemented, the borrowing and consuming parameters are disallowed on copyable types, in order to prevent incompatibility with the no-implicit-copy behavior. They will be allowed again when that support is implemented, which we plan to have ready soon.

5 Likes

Thanks! It appears that this has been allowed now, and I was able to verify that they function for C++ types as well.

1 Like

Thanks for confirming! Let us know if you do find problems.