Skip to content

Introduce a special DeclBaseName for "deinit" #10965

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 2 commits into from
Aug 1, 2017

Conversation

ahoppen
Copy link
Member

@ahoppen ahoppen commented Jul 14, 2017

Problem statement

Currently, destructors are represented by the known identifier "deinit", making it impossible to have a function or instance variable named "deinit" in a class. Declaring a function named "deinit" currently results in an error about an invalid redeclaration of deinit and adding an instance variable named "deinit" crashes the compiler.

Solution

Similar to how special DeclNames were introduced for subscripts to avoid the name collision between functions named "subscript" and proper subscripts, introduce a special DeclName for destructors and remove "deinit" from the list of known identifiers, making the identifier named "deinit" and the name representing the destructor completely distinct and thus resolving the above issue.

@ahoppen
Copy link
Member Author

ahoppen commented Jul 14, 2017

@swift-ci Please test

@@ -420,7 +420,7 @@ bool Decl::isPrivateStdlibDecl(bool whitelistProtocols) const {
if (auto AFD = dyn_cast<AbstractFunctionDecl>(D)) {
// Hide '~>' functions (but show the operator, because it defines
// precedence).
if (AFD->getNameStr() == "~>")
Copy link
Member Author

Choose a reason for hiding this comment

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

The only reference to the ~> operator I could find was in Policy.swift which stated that it is a workaround for rdar://problem/14011860. Is that still up to date? GenericDispatch.swift seems to test it but it's used nowhere in the standard library.

Copy link
Contributor

@jrose-apple jrose-apple Jul 14, 2017

Choose a reason for hiding this comment

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

Aha, yes, that's gone now that we have protocol extensions. Still, removing it entirely should probably be a separate PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, I'll have a look how much of it can be removed later on.

@@ -239,7 +239,8 @@ static void printValueDecl(ValueDecl *Decl, raw_ostream &OS) {

if (Decl->isOperator()) {
OS << '"' << Decl->getBaseName() << '"';
} else if (Decl->getBaseName() == "subscript") {
} else if (Decl->getBaseName() == "subscript" ||
Decl->getBaseName() == "deinit") {
Copy link
Member Author

@ahoppen ahoppen Jul 14, 2017

Choose a reason for hiding this comment

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

I'm not quite sure if we should escape deinit in SIL if used as a normal identifier. For subscripts we needed to, since otherwise the names of subscript getters/setters could have clashed with the getters/setters of instance variables named "subscript". AFAIK destructors in SIL always have the suffix !destructor so there's no name clash. Should we strive for consistency between the two keywords or simplicity on deinit? See the changes in vtables.swift for an example of how the dotted paths look like.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm still inclined to escape all keywords, always, but cc @swiftix, @jckarter.

Copy link
Member Author

Choose a reason for hiding this comment

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

@swiftix @jckarter Any opinion on whether "deinit" should be escaped or not?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, I forgot @swiftix was out on vacation. He'll be back tomorrow.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with Jordan. Escaping all keywords seems like the right conservative answer.

@ahoppen ahoppen force-pushed the deinit-special-name branch from 14f1d5f to c13bbbe Compare July 14, 2017 09:49
@ahoppen
Copy link
Member Author

ahoppen commented Jul 14, 2017

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test Linux Platform
Git Commit - 14f1d5fb1c4d211a3b59d769b0466c583a189e37
Test requested by - @ahoppen

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test OS X Platform
Git Commit - 14f1d5fb1c4d211a3b59d769b0466c583a189e37
Test requested by - @ahoppen

@ahoppen ahoppen changed the title WIP: Special name for deinit Special name for deinit Jul 14, 2017
@ahoppen ahoppen requested a review from jrose-apple July 14, 2017 15:16
Copy link
Contributor

@jrose-apple jrose-apple left a comment

Choose a reason for hiding this comment

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

Wow, this fell out very nicely. Good work, Alex.

@@ -548,6 +548,9 @@ void ASTMangler::appendDeclName(const ValueDecl *decl) {
case DeclBaseName::Kind::Subscript:
appendIdentifier("subscript");
break;
case DeclBaseName::Kind::Destructor:
// FIXME: Is it true that this is unreachable?
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm 90% sure this is true but try defining a local type inside a destructor to make sure.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, thanks for the reassurance.

@@ -5647,6 +5647,8 @@ class ConstructorDecl : public AbstractFunctionDecl {
GenericParamList *GenericParams,
DeclContext *Parent);

Identifier getName() const { return getFullName().getBaseIdentifier(); }
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we actually use this one? It's always going to be Id_init.

Copy link
Member Author

Choose a reason for hiding this comment

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

I left it in for consistency. You can call getName() on all Decls that are guaranteed to be backed by Identifiers. But I don't think it's actually used. Long term goal would be to remove it once/if Id_init becomes a special name as well.

@ahoppen ahoppen force-pushed the deinit-special-name branch from c13bbbe to 5002fce Compare July 14, 2017 17:09
@dabrahams
Copy link
Contributor

The way the PR description is phrased this sounds like some kind of troll. Just sayin' .

@ahoppen ahoppen changed the title Special name for deinit Introduce a special DeclBaseName for deinit Jul 14, 2017
@ahoppen ahoppen changed the title Introduce a special DeclBaseName for deinit Introduce a special DeclBaseName for "deinit" Jul 14, 2017
@ahoppen
Copy link
Member Author

ahoppen commented Jul 14, 2017

@dabrahams That's certainly not what I wanted. Thanks for the feedback. I've updated it and hope it sounds more serious now.

@ahoppen ahoppen force-pushed the deinit-special-name branch 2 times, most recently from 418ff0d to d18f196 Compare July 19, 2017 09:58
This name is not used yet
@ahoppen ahoppen force-pushed the deinit-special-name branch from d18f196 to 8a839ed Compare July 28, 2017 08:47
@ahoppen
Copy link
Member Author

ahoppen commented Jul 28, 2017

@jrose-apple Could you have another look through this? I think all the questions have been answered and your comments taken care of.

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test Linux Platform
Git Commit - 8a839ed81cafbb8de0f163d1d202d876fcdb0e01
Test requested by - @ahoppen

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test OS X Platform
Git Commit - 8a839ed81cafbb8de0f163d1d202d876fcdb0e01
Test requested by - @ahoppen

Copy link
Contributor

@jrose-apple jrose-apple left a comment

Choose a reason for hiding this comment

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

We left off with the question about escaping in SIL, and Joe agreed with me that it would be better to escape everything. But that doesn't have to be part of this patch, which is just about deinit. Yes, this looks good now!

No longer use the known identifier `deinit` for destructors. This allows
classes to have functions called `deinit`.
@ahoppen ahoppen force-pushed the deinit-special-name branch from 8a839ed to ebd701c Compare July 28, 2017 17:20
@ahoppen
Copy link
Member Author

ahoppen commented Jul 28, 2017

Ah, I see, I thought by all keywords you meant escaping all keywords that clashed with special decl names. I'll create another PR for it then.

@swift-ci Please test and merge

@ahoppen
Copy link
Member Author

ahoppen commented Aug 1, 2017

Test once again before merging since old test is already several days old.
Btw: Any idea why swift-ci wasn't able to merge the PR?

@swift-ci Please smoke test and merge

@ahoppen
Copy link
Member Author

ahoppen commented Aug 1, 2017

swift-ci didn't run. Let's try again

@swift-ci Please smoke test and merge

@swift-ci swift-ci merged commit 17ddc58 into swiftlang:master Aug 1, 2017
@ahoppen ahoppen deleted the deinit-special-name branch August 1, 2017 16:32
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.

5 participants