Ambiguous parsing of `return`


(Jens Alfke) #1

Someone on another forum (not directly related to Swift) just mentioned running into a confusing situation where they had added an early `return` to a method for testing purposes, in order to disable the code following it:

func myFunc() {
        // some code
        return
        cache.removeAll()
        // more code that is now skipped.
}

Unexpectedly, the line following the `return` still got executed, so "I couldn't figure out why my cache kept getting zapped.”

Turns out the Swift parser is interpreting this as `return cache.removeAll()`, which works because that expression returns void, which matches the function’s return type.

This seems like a case where the parser is playing by the rules, but the result is not what a human would expect. It would be better for a `return` on a line by itself to be parsed as a complete statement, without continuing to the next line. Is this already a known issue?

—Jens

PS: I’m sure someone will point out that adding an early return like this is sub-optimal, and the compiler could warn that the code following is unreachable. Which is true, and I use comments to disable code in situations like this. But I’m sure this developer’s not the only one who adds `return` instead.


(G B) #2

Sub-optimal or not, I’d call that unexpected behavior.

Does it make more sense to ensure return doesn’t take an argument in a function returning void?

···

On Jun 6, 2016, at 10:00 , Jens Alfke via swift-users <swift-users@swift.org> wrote:

Someone on another forum (not directly related to Swift) just mentioned running into a confusing situation where they had added an early `return` to a method for testing purposes, in order to disable the code following it:

func myFunc() {
        // some code
        return
        cache.removeAll()
        // more code that is now skipped.
}

Unexpectedly, the line following the `return` still got executed, so "I couldn't figure out why my cache kept getting zapped.”

Turns out the Swift parser is interpreting this as `return cache.removeAll()`, which works because that expression returns void, which matches the function’s return type.

This seems like a case where the parser is playing by the rules, but the result is not what a human would expect. It would be better for a `return` on a line by itself to be parsed as a complete statement, without continuing to the next line. Is this already a known issue?

—Jens

PS: I’m sure someone will point out that adding an early return like this is sub-optimal, and the compiler could warn that the code following is unreachable. Which is true, and I use comments to disable code in situations like this. But I’m sure this developer’s not the only one who adds `return` instead.
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Daniel Dunbar) #3

Did you try an example? Swift warns about this for this very reason:

$ cat x.swift 
func f0() {}

func f1() {
  return
  f0()
}

$ swiftc -c x.swift 
x.swift:5:3: warning: expression following 'return' is treated as an argument of the 'return'
  f0()
  ^

- Daniel

···

On Jun 6, 2016, at 10:00 AM, Jens Alfke via swift-users <swift-users@swift.org> wrote:

Someone on another forum (not directly related to Swift) just mentioned running into a confusing situation where they had added an early `return` to a method for testing purposes, in order to disable the code following it:

func myFunc() {
        // some code
        return
        cache.removeAll()
        // more code that is now skipped.
}

Unexpectedly, the line following the `return` still got executed, so "I couldn't figure out why my cache kept getting zapped.”

Turns out the Swift parser is interpreting this as `return cache.removeAll()`, which works because that expression returns void, which matches the function’s return type.

This seems like a case where the parser is playing by the rules, but the result is not what a human would expect. It would be better for a `return` on a line by itself to be parsed as a complete statement, without continuing to the next line. Is this already a known issue?

—Jens

PS: I’m sure someone will point out that adding an early return like this is sub-optimal, and the compiler could warn that the code following is unreachable. Which is true, and I use comments to disable code in situations like this. But I’m sure this developer’s not the only one who adds `return` instead.
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Jens Alfke) #4

I don’t get that warning with the latest Xcode 7.3.1 (Swift 2.3 IIRC.) Perhaps you’re using Swift 3? Outside of this community I don’t think many people are using Swift 3 yet.

—Jens

···

On Jun 6, 2016, at 11:46 AM, Daniel Dunbar <daniel_dunbar@apple.com> wrote:

Did you try an example? Swift warns about this for this very reason:


(Chris Lattner) #5

Yes, this is a new warning produced by Swift 3, specifically introduced to address this issue.

file.swift:3:5: warning: expression following 'return' is treated as an argument of the 'return'
    f0()
    ^
file.swift:3:5: note: indent the expression to silence this warning
    f0()
    ^
-Chris

···

On Jun 6, 2016, at 11:50 AM, Jens Alfke via swift-users <swift-users@swift.org> wrote:

On Jun 6, 2016, at 11:46 AM, Daniel Dunbar <daniel_dunbar@apple.com <mailto:daniel_dunbar@apple.com>> wrote:

Did you try an example? Swift warns about this for this very reason:

I don’t get that warning with the latest Xcode 7.3.1 (Swift 2.3 IIRC.) Perhaps you’re using Swift 3? Outside of this community I don’t think many people are using Swift 3 yet.