-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Inherit doc comments from default implementations of inherited protocols #73066
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
Inherit doc comments from default implementations of inherited protocols #73066
Conversation
lib/AST/DocComment.cpp
Outdated
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.
| /// Check if there is an inherited protocol that has a default implementaiton | |
| /// Check if there is an inherited protocol that has a default implementation |
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.
Could add a test for the case where there is both a requirement and a default
619a27a to
bdfe29f
Compare
|
@swift-ci Please smoke test |
lib/AST/DocComment.cpp
Outdated
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.
What if VD is defined in an extension? Do we want to support that?
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.
We do with the lines below, right?
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.
That only handles protocol extensions, right? I was thinking of e.g a struct extension
bdfe29f to
a174859
Compare
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.
@QuietMisdreavus This comments seems to imply the exact opposite of what I want to achieve in this PR. Is there any reason why we didn’t want to inherit documentation from extensions?
For context, the concrete example I want to fix with this PR is that this implementation of _ArrayProtocol.filter https://github.com/apple/swift/blob/c531f2914fda0b84d8af091a0081799101f76d9b/stdlib/public/core/ArrayType.swift#L73-L78 should inherit the documentation from the documentation of Sequence.filter, which is implemented in an extension https://github.com/apple/swift/blob/5df0f053d95c1143ac34ac88faafdfa3902a3224/stdlib/public/core/Sequence.swift#L717-L739
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.
cc @franklinsch (and possibly also @bitjammer for the underlying discussion of inheriting docs in the first place)
I think it should respect the presence of the -skip-inherited-docs flag, but otherwise i don't remember off the top of my head.
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.
I think we already respect the -skip-inherited-docs flag because we’re not calling into getDocCommentProvidingDecl if it is set and this PR only modifies getDocCommentProvidingDecl
lib/AST/DocComment.cpp
Outdated
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.
Should this be the other way around? e.g allowing:
protocol P {}
extension P {
/// hello
func foo() -> Int? { 0 }
}
struct S: P {
func foo() -> Int { 0 }
}But not:
protocol P {}
extension P {
/// hello
func foo() -> Int { 0 }
}
struct S: P {
func foo() -> Int? { 0 }
}Not that these are really overrides anyway, but if we want similar type-matching rules, then I think it makes sense to flip the ordering.
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.
Oh, yes. I thought that I had this case covered with the throws case but apparently throws works either way 🤷🏽
lib/AST/DocComment.cpp
Outdated
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.
Thought of a couple more edge cases :)
- static mismatch
protocol P {}
extension P {
/// hello
static func foo() {}
}
struct S: P {
func foo() {}
}
func bar(_ x: S) {
x.foo()
}- enum case matching a function (if we want this to work it would need to be a static function)
protocol P {}
extension P {
/// hello
func foo(_ x: Int) -> E { .foo(0) }
}
enum E: P {
case foo(Int)
}
func bar(_ x: E) {
E.foo(0)
}- this is quite silly, but technically this would match:
class C {
/// hello
struct foo {}
}
class D: C {
var foo: C.foo.Type { C.foo.self }
}
func bar(_ x: D) {
let y = x.foo
}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.
Good cases, thanks. Case 3 does inherit but I decided to not care and not add a test case for it. If it broke, I don’t think we would care.
lib/AST/DocComment.cpp
Outdated
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.
Wonder if we ought to have a utility for removing the curried self, could be used in a couple of other places:
a174859 to
0795102
Compare
|
@swift-ci Please smoke test |
0795102 to
d2b3942
Compare
|
@swift-ci Please smoke test |
lib/AST/DocComment.cpp
Outdated
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 just duplicating logic in the witness checker. Default witnesses are recorded in the ProtocolDecl.
See TypeChecker::inferDefaultWitnesses() and ProtocolDecl::getDefaultWitness().
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.
That’s not sufficient though. We aren’t dealing with protocol requirements here, just default methods on a protocol.
For example in the following test, InheritedProtocol.hello() needs to inherit the documentation from BaseProtocol.hello but there is no protocol requirement that hello() can be a witness for. Any suggestion of how to implement that without my implementation?
protocol BaseProtocol {}
extension BaseProtocol {
/// Say hello
func hello() { }
}
protocol InheritedProtocol: BaseProtocol {}
extension InheritedProtocol {
func hello() { }
}For example when we have
```swift
protocol BaseProtocol {}
extension BaseProtocol {
/// Say hello
func hello() { }
}
struct MyStruct: BaseProtocol {
func hello() {}
}
```
Then `MyStruct.hello` should inherit the doc comment from the implementation of `BaseProtocol.hello`. Currently no doc comment is associated with `MyStruct.hello`.
rdar://126240546
d2b3942 to
eec3d75
Compare
|
@swift-ci Please smoke test Linux |
For example when we have
Then
MyStruct.helloshould inherit the doc comment from the implementation ofBaseProtocol.hello. Currently no doc comment is associated withMyStruct.hello.rdar://126240546
The changes in offsets in the test cases is because
init(rawValue:)now inherits the doc comment ofRawRepresentable, which shifts the lines in generated interfaces around.