Skip to content
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

[Sema] Diagnose missing 'nil' in failable initializer return #30707

Closed
wants to merge 2 commits into from

Conversation

HassanElDesouky
Copy link
Contributor

If you create a failable initializer and accidentally add a simple return rather than return nil, will show an error and provide a fix to add nil to the return statement.

Resolves SR-12421.

@HassanElDesouky
Copy link
Contributor Author

@xedin @LucianoPAlmeida Please, review.

// show an error and provide a fix
if (auto ctor = dyn_cast_or_null<ConstructorDecl>(
TheFunc->getAbstractFunctionDecl())) {
if (ctor->isFailable()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

@HassanElDesouky As I mentioned in the last comment on the issue, I think this is already correct...
Because when a ReturnStmt has no result !RS->hasResult() it is a return or an implicit return, so this would be also valid inside a failable init.
Here an example:

init?(label: String?) { 
         guard let actualLabel = label else {
             return nil
         }

         self.label = actualLabel
         return // You could add an explicit return
     }
init?(label: String?) { 
         guard let actualLabel = label else {
             return nil
         }

         self.label = actualLabel
     } // There is an implicit return statement here I think

In both examples the code is valid :)
So in my opinion, if the incorrect message from the SR is fixed on master and this is already fixed. And you could just add the test case here
cc @xedin

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm sorry I don't quite understand. So you are suggesting to just remove all of this and a test case?
If so... which diagnostic this should be diagnosed to?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@LucianoPAlmeida I don't have a master branch, the master branch isn't compiling on Ubuntu. You can check the error message here Therefore, I'm on an older branch.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, just edited the previous comment, but what I mean is that I think this code is already correct if it compiles and it shouldn't be diagnosed because is valid code like the examples. So it shouldn't be diagnosed.
And if this code compiles on master, I think the issue is already fixed :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I understand now, thank you! However, what do you mean by "you could just add the test case here"?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, I agree with @LucianoPAlmeida. This is something that should be handled in SIL diagnostics and not the typechecker. Anyway, this case is already handled by DefiniteInitialization:

// swiftc -emit-sil
/Users/suyashsrijan/Desktop/test.swift:3:5: error: constant 'self.label' used before being initialized
    init?(label: String?) {
    ^

as described in the JIRA ticket, but I don't think we can assume that every return must be a return nil (as shown in the examples above), so it might be a bit tricky to detect the right "exits" where a return nil is the right answer.

Copy link

Choose a reason for hiding this comment

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

I would argue that in a failable initialiser any return before all properties are initialised should be an error (at the return, not at the init, as that is where the error actually is). I would also argue that the compiler should provide a fix-it to convert it to a return nil as the user forgetting the nil part is the most likely cause of the error (and is something the current error message and location don't actually explain in any way)

Copy link
Collaborator

Choose a reason for hiding this comment

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

so it might be a bit tricky to detect the right "exits" where a return nil is the right answer

Agree @theblixguy, I was thinking in something like tweak the wording of diagnostic message for cases like this to something like 'self.label' should be initialized on all paths/branches..., when there is no explicit reference to the member in at least one of the paths ... maybe this could make it more clear.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would also argue that the compiler should provide a fix-it to convert it to a return nil as the user forgetting the nil part is the most likely cause of the error

Humm, since in failable inits that's the most commom way people use return it makes sense

Copy link
Member

Choose a reason for hiding this comment

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

I agree with @pilky. It seems like the problem here is that return without nil should be diagnosed in situations when it's used before all of the properties are initialized. Which seems like it belongs in SIL diagnostics.

@shahmishal
Copy link
Member

Please update the base branch to main by Oct 5th otherwise the pull request will be closed automatically.

  • How to change the base branch: (Link)
  • More detail about the branch update: (Link)

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.

None yet

6 participants