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

[SR-2028] "return" in func returning void should not have an argument #44637

Open
swift-ci opened this issue Jul 8, 2016 · 7 comments
Open

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Jul 8, 2016

Previous ID SR-2028
Radar None
Original Reporter swifdy19%7 (JIRA User)
Type Bug
Environment

Xcode 8.0 beta (8S128d), Swift 3

Additional Detail from JIRA
Votes 6
Component/s Compiler
Labels Bug, DiagnosticsQoI, Parser
Assignee None
Priority Medium

md5: 48aff532232ae357d7d9a61770f616ba

Issue Description:

func test()
{
    return   // Warning: Expression following 'return' is treated as an 
                    // argument of the 'return'
        
    print("foo")      // should not print, but it does
}
@belkadan
Copy link
Contributor

belkadan commented Jul 8, 2016

I'm not sure the compiler should treat Void-returning functions differently, especially when closures often have inferred return types.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Feb 8, 2018

Comment by Christopher Brandow (JIRA)

I just ran into this today, and I think this is not unexpected behavior to many users. While the compiler did produce a warning in my case, depending on spacing/tabs, a compiler error may not appear: http://johnszumski.com/blog/unexpected-edge-case-with-swifts-return .

While trailing closures are a common pattern, the lack of required semi-colons in Swift do, I think, lead many programmers to lazily equate a newline with a semicolon, which is not precisely correct.

Adding an explicit notation in order to execute code on newlines after a `return` would be a small price to pay for clarity in a language that does not require semi-colons. (as suggest by author of linked blogpost)

@swift-ci
Copy link
Collaborator Author

swift-ci commented Feb 13, 2018

Comment by Wes Campaigne (JIRA)

If a programmer puts a return statement in a Void-returning function, I think that's a pretty clear signal that they wish the control flow to end at that point. Maybe I'm missing something related to trailing closures but I don't see how there's a use case for evaluating a Void expression as an argument to `return`, instead of forcing the programmer to have an empty return statement after the expression.

Put another way: Swift has been very good at conditioning programmers to assume that a newline will end the statement except when there's a clear syntactic reason why it shouldn't, and the idea that Swift will view `return \n` in a Void-returning function as an incomplete statement (that should consume the subsequent expression) is non-obvious and unintuitive.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Sep 28, 2018

Comment by Mark A. Donohoe (JIRA)

Well I just wasted a good half-hour trying to debug why code was running when I was damn near sure it wasn't supposed to be![]( In my case, I was testing a didSet observer and wanted to bail out at a particular point, so rather than highlighting, then commenting out everything, I just tossed in a 'return' statement, then started getting unexpected results since the next line after the return was still being executed. Talk about confusing)!![]( I've been a Swift dev for years now and have never come across this completely unintuitive behavior)

It wasn't until I changed the indentation that a warning popped up telling me what the real issue was. Had I not touched the indentation, I wouldn't have seen it, and would still be scratching my head.

To me this is definitely a bug![]( There should be no closure after a return. If there is, come up with explicit syntax) Swift is supposed to be really great at being clear, and this time, even to a very experienced dev, left me falling flat on my face and I only got to the bottom of it by accident. Very un-Swifty if you will. (Honestly, I'd say this is a critical bug, but considering as I said, it's the first time I've ever seen this, it would be weird. Then again, it only takes one car crash, right?!

@sveinhal
Copy link

sveinhal commented Dec 30, 2019

It is common to “exploit” this in functions that take a completion handler (which is “kinda” like a return value) where you want to both exit from the function, and also call the completion handler.

guard condition else { return completion(nil) }

Etc.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Mar 8, 2021

Comment by Flower (JIRA)

I just spend half a hour trying to find a bug in my code, because closure, which written below return handler in running.

The main problem, that Xcode showed a warning message: "Expression following 'return' is treated as an argument of the 'return'", but I'm used to the message being shown in this case "Code after 'return' will never be executed" and I just didn't pay attention to this message.

I don't know if this behavior needs to be changed.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Mar 8, 2021

Comment by Christopher Brandow (JIRA)

definitely counter intuitive. While I now understand (vaguely) what the compiler is doing, I think that triggering that behavior should require explicit syntax, like `return executionOf({ closure })`.

other than syntactic savings, I haven't seen any case where this is helpful.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants