-
Notifications
You must be signed in to change notification settings - Fork 10.5k
ASTPrinter: Mutability fixes for protocol stubs #24277
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
ASTPrinter: Mutability fixes for protocol stubs #24277
Conversation
cfc0148
to
b7d4f61
Compare
cc @jrose-apple |
This seems wrong: we do want to print |
I see, that makes sense. I got too carried away reasoning from a different perspective: that I will enable it on structs in a moment. |
Enums too; it's classes that are special. I think the stubs are supposed to be "a reasonable default", but I could see how they could be interpreted as "the minimum set of requirements". |
d77dbf7
to
0173e1e
Compare
@jrose, do you approve? |
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.
Thanks for working on this!
if (isClass) | ||
Options.ExcludeAttrList.push_back(DAK_Mutating); | ||
// Struct methods are non-mutating be default. | ||
if (isClass || !isa<AbstractStorageDecl>(Requirement)) |
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 don't think this qualification is necessary. You're not allowed to write nonmutating
on a non-accessor anyway. May as well just put both conditions under isClass
.
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.
You're not allowed to write
nonmutating
on a non-accessor anyway
Am I? nonmutating
is allowed on protocol method requirements, which makes sense, but it appears we can also write it on value type methods in Swift 5, which is obviously redundant.
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.
Um. It doesn't even make sense for protocol requirements, but you're right that it's not rejected. I did not realize 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.
It doesn't even make sense for protocol requirements
Oh, right, of course.
lib/Sema/TypeCheckProtocol.cpp
Outdated
@@ -2657,6 +2657,16 @@ printRequirementStub(ValueDecl *Requirement, DeclContext *Adopter, | |||
Options.FunctionDefinitions = true; | |||
Options.PrintAccessorBodiesInProtocols = true; | |||
|
|||
bool isClass = AdopterTy->is<ClassType>(); |
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 will only be true for non-generic classes. A simpler way to check is AdopterTy->getSelfClassDecl() != nullptr
.
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.
Oops, ClassType
is indeed misleading, thanks!
@@ -0,0 +1,4 @@ | |||
public protocol ExternalMutabilityProto { | |||
mutating func foo() | |||
subscript() -> Int { get nonmutating set } |
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.
If you want to be extra thorough, you could check how mutating get
prints as well.
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 also noticed that we never print accessors for property requirements, even when the getter is required to be mutating or the setter - non-mutating. Imagine how confusing a conformance error can be in the non-mutating case.
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.
The getter can't be required to be mutating, just allowed to be mutating. But the setter case would force you into a computed property, and so the stubs for that could include the computed property structure. Let's save that for another PR, though.
@@ -2768,7 +2768,7 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) { | |||
if (!Options.SkipIntroducerKeywords) { | |||
if (decl->isStatic() && Options.PrintStaticKeyword) | |||
printStaticKeyword(decl->getCorrectStaticSpelling()); | |||
if (decl->isMutating() && !decl->getAttrs().hasAttribute<MutatingAttr>()) { |
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.
Is this part not relevant? I assumed it kept mutating
from being printed twice in some cases.
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.
Not anymore I believe, since I chose to skip mutability modifiers in printAttributes
.
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.
FYI this caused interface generation to print mutating mutating
for explicitly mutating functions, because the changes made to printAttributes
only applied to implicit attributes. Fixed: #30183
@swift-ci Please test |
Build failed |
Build failed |
:-( Looks like the duplicate |
589d66a
to
6f119b0
Compare
@jrose Turns out I forgot to skip them for functions as well. I don't know which tests failed now that the job is gone, though. Let's see if the duplication is still present? |
@swift-ci please test |
Looks pretty good now. Are there already tests for |
Yes, though I do print |
Build failed |
That LLDB test was recently disabled, let's go again. @swift-ci Please smoke test macOS |
Fix double-printing |
mutating
in protocol stubs inside classes (this did happen to stubs for mutating requirements when the protocol and conformer were in different modules).nonmutating
for non-mutating setters in structs.The AST printer would benefit from a better distinction between attributes and modifiers, but I think it is fine to implement it this way, for now :)