Skip to content

Allow Copyable Types To Elide Ownership Conventions #16999

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 1 commit into from
Jun 19, 2018

Conversation

CodaFi
Copy link
Contributor

@CodaFi CodaFi commented Jun 5, 2018

Allow witnesses to protocols in a copyable context to elide explicit
ownership conventions. This allows clients like the standard library to
standardize on one ownership convention without an ABI or API breaking
change in 3rd party code.

In the future, moveonly contexts must disallow this default behavior
else the witness thunks could silently transfer ownership.

rdar://40774922

protocol P {
  __consuming func implicit(x: __shared String)
  __consuming func explicit(x: __owned String)
  __consuming func mismatch(x: __shared String)
}

class C : P {
  // C.implicit(x:) takes self and x '@guaranteed' thru the witness thunk
  func implicit(x: String) {}
  // C.explicit(x:) takes self and x @owned with no convention changes
  __consuming func explicit(x: __owned String) {}
  // Would inherit __consuming, but x has been spelled __owned so the requirement match fails.
  func mismatch(x: __owned String) {}
}

@CodaFi CodaFi requested a review from jckarter June 5, 2018 04:19
@CodaFi
Copy link
Contributor Author

CodaFi commented Jun 5, 2018

@swift-ci please smoke test

@jckarter
Copy link
Contributor

jckarter commented Jun 5, 2018

Does this work with retroactive conformances too?

@CodaFi
Copy link
Contributor Author

CodaFi commented Jun 5, 2018

Changing (non-defaulted) ownership conventions is an ABI-incompatible change.

@jckarter
Copy link
Contributor

jckarter commented Jun 5, 2018

You can still thunk in the witness (for copyable types), though. These annotations in a protocol requirement shouldn't be a source-affecting change for any copyable type witnesses.

@CodaFi
Copy link
Contributor Author

CodaFi commented Jun 5, 2018

I’ll add a test for the thunking then. I’ve got to clean up the commit log anyways.

@slavapestov
Copy link
Contributor

I’m not sure I like this. Confirming to a protocol should not change the types of witnesses. Instead, the witness thunk should handle convention changes.

@jckarter
Copy link
Contributor

jckarter commented Jun 7, 2018

@slavapestov Yeah, now that you mention it, that's more the model I had in mind too. Trying to push the convention attributes onto witnessing declarations could also lead to ABI breaks at a distance if you add a protocol conformance.

@CodaFi
Copy link
Contributor Author

CodaFi commented Jun 10, 2018

Conforming to a protocol should not change the types of witnesses.

The witnesses shouldn't be allowed to break the interface of their parents. Especially when we have moveonly contexts, the ability to e.g. share in a non-generic context where you would otherwise consume when directly using the witness doesn't seem desirable.

Trying to push the convention attributes onto witnessing declarations could also lead to ABI breaks at a distance if you add a protocol conformance.

Retroactive modelling is a known ABI break but wouldn't it be less of a concern now that we're mangling conventions in? If you tried to swap a binary framework that changed conventions you should get linker errors.

@jckarter
Copy link
Contributor

The witnesses shouldn't be allowed to break the interface of their parents. Especially when we have moveonly contexts, the ability to e.g. share in a non-generic context where you would otherwise consume when directly using the witness doesn't seem desirable.

For copyable types, though, there is no difference in the user interface. The ABI is an implementation detail.

Retroactive modelling is a known ABI break but wouldn't it be less of a concern now that we're mangling conventions in? If you tried to swap a binary framework that changed conventions you should get linker errors.

The ABI break seems gratuitous in this case. If a library wants to make a public type conform to a new protocol, it should be allowed to without breaking ABI.

@CodaFi CodaFi changed the title Allow inheriting ownership conventions Allow Copyable Types To Elide Ownership Conventions Jun 12, 2018
@CodaFi CodaFi force-pushed the witness-tampering branch from 69d6267 to 335212a Compare June 12, 2018 20:58
@CodaFi
Copy link
Contributor Author

CodaFi commented Jun 12, 2018

For those that are watching this thread/go digging for it in the future: There was a misunderstanding here.

Witnesses to protocol requirements in a copyable context may elide ownership requirements. We will not change the calling convention of the witness and must thunk to it. If the author of the witness cares about the behavior of the witness thunk - say for performance purposes - they must make sure that they explicitly annotate with the requirement's very same ownership conventions. Otherwise, we are at liberty to copy or borrow.

In a future moveonly context, these concerns are allayed by the fact that we simply won't allow ownership convention changes in witness thunks by virtue of Sema rejecting the protocol conformance.

@CodaFi CodaFi force-pushed the witness-tampering branch from 335212a to 10f25c1 Compare June 12, 2018 21:06
Allow witnesses to protocols in a copyable context to elide explicit
ownership conventions.  This allows clients like the standard library to
standardize on one ownership convention without an ABI or API breaking
change in 3rd party code.

In the future, moveonly contexts must disallow this default behavior
else the witness thunks could silently transfer ownership.

rdar://40774922

protocol P {
  __consuming func implicit(x: __shared String)
  __consuming func explicit(x: __owned String)
  __consuming func mismatch(x: __shared String)
}

class C : P {
  // C.implicit(x:) takes self and x '@guaranteed' thru the witness thunk
  func implicit(x: String) {}
  // C.explicit(x:) takes self and x @owned with no convention changes
  __consuming func explicit(x: __owned String) {}
  // Would inherit __consuming, but x has been spelled __owned so the requirement match fails.
  func mismatch(x: __owned String) {}
}
@CodaFi CodaFi force-pushed the witness-tampering branch from 10f25c1 to 9bd02e1 Compare June 19, 2018 19:26
@CodaFi
Copy link
Contributor Author

CodaFi commented Jun 19, 2018

@swift-ci please smoke test

@CodaFi
Copy link
Contributor Author

CodaFi commented Jun 19, 2018

⛵️

@CodaFi CodaFi merged commit 67ac2fd into swiftlang:master Jun 19, 2018
@CodaFi CodaFi deleted the witness-tampering branch June 19, 2018 21:01
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.

3 participants