Open hamishknight opened 6 years ago
Seems reasonable to me as well. @slavapestov, what do you think?
@DougGregor added a Swift 3 compatibility hack but it's still an error in Swift 4 mode. I'd rather it was an error too, otherwise you can write confusing and redundant things like "class Foo : AnyObject {}".
The error was intentional, and I think we should keep it. The superclass of a class is the single most important aspect of its definition, and should be called out explicitly, rather than buried behind a protocol composition. This same logic is why the superclass needs to be written first in the comma-separated list.
I agree regarding the superclass having to be stated explicitly in the inheritance clause, I filed SR-8151 for that. But I still think it's reasonable to state a conformance to a protocol composition that happens to contain AnyObject
(furthermore I think that class C : AnyObject
should be a warning rather than an error).
But if we are to continue rejecting these, should we also reject struct S : Any
? I'm currently working on implementing a warning for it over at https://github.com/apple/swift/pull/17425, which I guess could be used to stage it in to an error if desired.
I agree that it makes sense to state conformance to a protocol composition that contains ``AnyObject``, or even a class bound--so long as the class satisfies the class bound. For example, we currently error on this:
protocol P { }
class C { }
typealias CP = C & P
class D: C { }
class E: D, CP { } // error: multiple inheritance from classes 'D' and 'C'
which seems wrong to me: the superclass is "D" (it's right there in the correct place!), and we should be checking that E inherits from C.
Now, I think it's reasonable to warn if a particular type in the list doesn't contribute anything, so "struct S: Any" and "class C: AnyObject" are reasonable to warn about, because "Any" and "AnyObject" contribute no information... but that's not an error, that's a "you did something meaningless, are you sure that's what you meant?" warning.
Re-opening based on Doug's response.
Environment
Apple Swift version 3.1-dev (LLVM 9cb6a3ccee, Clang f38438fc01, Swift b5b79f88f6) Target: x86_64-apple-macosx10.9 Apple Swift version 4.1.2 (swiftlang-902.0.54 clang-902.0.39.2) Target: x86_64-apple-darwin17.6.0Additional Detail from JIRA
| | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug, 4.0Regression, TypeChecker | |Assignee | None | |Priority | Medium | md5: 8a66f8482ae9d01a49d646d0c08030b5Issue Description:
In Swift 3.1, it was possible to inherit from a protocol composition containing AnyObject through a type alias:
However in Swift 4, both the above example in Swift 3 mode and the equivalent Swift 4 spelling no longer compile (presumably due to the fact that AnyObject is no longer an actual protocol):
I would argue that this is a useful feature to have – being able to have a list of protocol constraints in a typealias along with the requirement of being a class, and then being able to directly conform a class to this typealias.
Especially given the fact that this is legal: