-
Notifications
You must be signed in to change notification settings - Fork 10.5k
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
Turn on the Copyable
as an inferred generic constraint by default
#64059
Conversation
There was a problem hiding this 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 !
3b2c9f3
to
94acc16
Compare
a2db4ed
to
1977880
Compare
@swift-ci please test |
9f40668
to
221d38c
Compare
@swift-ci please test and merge |
test/Constraints/members.swift
Outdated
@@ -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'}} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
221d38c
to
8c50906
Compare
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.
8c50906
to
8406699
Compare
@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.
@swift-ci please test macos platform |
@swift-ci please test linux platform |
In terms of full tests, this looks good to merge. The linux failure was just a |
@swift-ci please smoke test and merge |
This is the main thing required before we can make noncopyable / move-only types available by default (without a flag).
resolves rdar://104898230