Skip to content

Turn on the Copyable as an inferred generic constraint by default #64059

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 5 commits into from
Mar 5, 2023

Conversation

kavon
Copy link
Member

@kavon kavon commented Mar 3, 2023

This is the main thing required before we can make noncopyable / move-only types available by default (without a flag).

resolves rdar://104898230

Copy link
Contributor

@ktoso ktoso left a comment

Choose a reason for hiding this comment

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

Huh, sweet, thanks for the fix @kavon !

@kavon kavon force-pushed the staging-bootstrap-with-copyable branch from 3b2c9f3 to 94acc16 Compare March 3, 2023 05:31
@kavon kavon force-pushed the staging-bootstrap-with-copyable branch 3 times, most recently from a2db4ed to 1977880 Compare March 3, 2023 06:33
@kavon kavon marked this pull request as ready for review March 3, 2023 06:33
@kavon
Copy link
Member Author

kavon commented Mar 3, 2023

@swift-ci please test

@kavon kavon force-pushed the staging-bootstrap-with-copyable branch 2 times, most recently from 9f40668 to 221d38c Compare March 4, 2023 03:06
@kavon
Copy link
Member Author

kavon commented Mar 4, 2023

@swift-ci please test and merge

@@ -737,7 +737,7 @@ func rdar66891544() {
func foo<T>(_: T, defaultT: T? = nil) {}
func foo<U>(_: U, defaultU: U? = nil) {}

foo(.bar) // expected-error {{cannot infer contextual base in reference to member 'bar'}}
foo(.bar) // expected-error {{type '_Copyable' has no member 'bar'}}
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a diagnostic regression, there is no contextual type to infer .bar from because U is just a generic parameter without any protocol requirements.

Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps we should more generally do this for all marker protocols; a diagnostic like `type 'Sendable' has no member 'bar'" would be somewhat unexpected too for the same reason.

Copy link
Contributor

@xedin xedin Mar 4, 2023

Choose a reason for hiding this comment

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

Yeah, implicit conformances to marker protocols should not propagate (I am not sure about how Sendable behaves, haven’t reviewed any PRs for it).

Copy link
Member Author

Choose a reason for hiding this comment

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

sure, I could make it general to exclude all marker protocols.... but you're allowed to add members to a marker protocol via extension, though you can't add static members:

extension Sendable {
  var member: Int { return 100 }
  typealias buddy = Int
}

func take<T: Sendable>(_ t: T) {}

func pass() {
  take(.member)    // error: instance member 'member' cannot be used on type 'Sendable'
  take(.nonmember) // error: type 'Sendable' has no member 'nonmember'
  take(.buddy)     // OK
}

so if I exclude marker protocols, all three calls turn into errors with "cannot infer contextual base in reference to member ...".

Since _Copyable is marked unavailable, you can't extend it, so nobody can add members to it.

Copy link
Member Author

@kavon kavon Mar 4, 2023

Choose a reason for hiding this comment

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

Then again, I don't know why anyone would want to add members to Sendable so I guess not inferring it is fine. They need to make it explicit. That change is worth doing in a different PR since it might lead to a source break.

Copy link
Contributor

Choose a reason for hiding this comment

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

Since it’s not possible to add static members it shouldn’t be included because leading-dot syntax in generic context only works when first member in the chain is static.

Copy link
Contributor

Choose a reason for hiding this comment

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

Just to clarify - it shouldn’t be included if it’s not stated explicitly, your example should still infer Sendable.

@kavon kavon force-pushed the staging-bootstrap-with-copyable branch from 221d38c to 8c50906 Compare March 4, 2023 19:21
kavon added 3 commits March 4, 2023 11:42
The _Copyable constraint was implemented as a marker protocol.
That protocol is part of the KnownProtocol's in the compiler.
When `ASTContext::getProtocol(KnownProtocolKind kind)` tries
to find the ProtocolDecl for Copyable, it will look in the
stdlib module (i.e., Swift module), which is where I initially
planned to put it.

That created problems initially when some regression tests
use `-parse-stdlib` failed to do that protocol lookup, which is
essential for adding the constraint (given the current implementation).

That led to believe we need to pull Copyable out of the stdlib, but that's
wrong. In fact, when building the Swift module itself, we do `-parse-stdlib`
but we also include `-module-name Swift`. This causes the _Copyable protocol
defined in the Stdlib to be correctly discovered while building the stdlib
itself (see the test case in this commit). So, the only downside of
having the Copyable protocol in the Stdlib is that `-parse-stdlib` tests
in the compiler can't use move-only types correctly, as they'll be
allowed in generic contexts. No real program would build like this.

Until I have time to do a further refactoring, this is an acceptable trade-off.

fixes rdar://104898230
Since these tests may in the future have
a move-only type in it. If you're using
`-parse-stdlib -module-name Swift`
it's a good add Copyable, but not required,
at this time.
@kavon kavon force-pushed the staging-bootstrap-with-copyable branch from 8c50906 to 8406699 Compare March 4, 2023 19:45
@kavon
Copy link
Member Author

kavon commented Mar 4, 2023

@swift-ci please test and merge

the way these diagnostics were added seems to have been through score hacking
and I haven't been able to get the behavior back since introducing the
copyable type constraint for generics. I've logged restoring this as a TODO
to take care of sometime later when I have more time.
@kavon
Copy link
Member Author

kavon commented Mar 5, 2023

@swift-ci please test macos platform

@kavon
Copy link
Member Author

kavon commented Mar 5, 2023

@swift-ci please test linux platform

@kavon
Copy link
Member Author

kavon commented Mar 5, 2023

In terms of full tests, this looks good to merge. The linux failure was just a Swift-validation(linux-x86_64) :: SIL/parse_stdlib.sil assertion failure not caused by this PR. The macos failure most recently was just CI flakiness with BreakpointSimple. Windows passed earlier.

@kavon
Copy link
Member Author

kavon commented Mar 5, 2023

@swift-ci please smoke test and merge

@swift-ci swift-ci merged commit b159576 into swiftlang:main Mar 5, 2023
@kavon kavon deleted the staging-bootstrap-with-copyable branch March 5, 2023 17:25
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.

6 participants