ceylon icon indicating copy to clipboard operation
ceylon copied to clipboard

fix or disallow 'break' and 'continue' in 'finally'

Open jvasileff opened this issue 8 years ago • 5 comments

break (and likely continue) in finally can create confusing definite initialization scenarios that aren't properly handled by the type checker.

It may make sense to disallow them (and return too, for good measure?)

Here's an example where break is used to "skip past" a return statement, which confuses the type checker:

shared void run() {
    String s;
    while (true) {
        try {
            if (1==2) {
                s = "hello";
                break; // if the type checker were smarter, we could comment out this line
            } else {
                return;
            }
        } finally {
            break; // skips over the "return" in "else" above
        }
    }
    print(s); // prints "<null>"!  (or on the JVM, a backend error)
}

jvasileff avatar Oct 03 '17 04:10 jvasileff

By the way, I haven't tried it, but I remember someone saying that C# disallows this.

ghost avatar Oct 04 '17 06:10 ghost

Yeah, I think they made the right decision with C#. These things are too confusing to possibly be useful.

jvasileff avatar Oct 04 '17 16:10 jvasileff

This one (not involving finally) also compiles:

shared void run() {
    String s;
    while (true) {
        try {
            throw;
        } catch (e) {
            break;
        }
    }
    print(s);
}

jvasileff avatar Oct 04 '17 19:10 jvasileff

@jvasileff so I've done two things:

  1. I've fixed the definite assignment checking for the scenario of break in finally, so at least the two cases you provided are correctly detected as errors by the typechecker.
  2. I've added warnings for any sort of control directive within a finally block. This seems reasonable to me: finally blocks definitely aren't for doing break/return/continue. However, I'm not certain about throw. I've certainly seen people throw from finally, and, though I don't like it, perhaps you need to sometimes?

WDYT? Is this a good solution?

gavinking avatar Apr 28 '18 20:04 gavinking

I believe throw should always be allowed without warning (and, it’s unrelated to the initialization issue, and exceptions can occur in any code anyway), but otherwise that sounds reasonable to me.

jvasileff avatar Apr 30 '18 13:04 jvasileff