> Le 4 mai 2016 à 11:55, Pyry Jahkola <[email protected]> a écrit :
> 
> Hi Gwendal,
> 
> Nice writeup. So I see that you recognise how this extra specification will 
> complicate (while also facilitate) things. And I also see that you're a 
> co-author of the proposal. So I'm more than happy if you can squeeze this 
> extra into it.
> 
> However reading your example code, I had to squint to see—without the 
> compiler's squiggly red aid—what all the problematic cases are.
> 
> 1) Is it obvious to everybody why you can't always use `x` in the end of 
> Cases 2 and 4? For example, with `if—else` you MUST initialise the variable 
> or escape its scope in all branches; you can't just write the following to 
> complete the initialisation later:
> 
>     let x: Int
>     if cond { x = 1 }
>     // ...
>     if !cond { x = 2 } // too late!
> 2) Should Cases 2 and 4 be made illegal? The requirement could then be that 
> all `catch` blocks either:

Hello Pyry,

In case 2 and 4, you can't always use `x` at the end because there are code 
paths that do not initialize x.

Let's repeat the case 2 and 4, as a reminder:

Case 2:

        // Function which rethrows closure errors:
        func f1(closure: @noescape(once) () throws -> ()) rethrows {
                try closure()
        }
        let x: Int
        do {
                try f1 {                        
                        x = try getX()
                        // use x
                }
                // use x
        } catch {
                // can't use x
        }
        // can't use x

Case 4:

        // Function which may throw before, inside, or after the closure:
        func f2(closure: @noescape(once) () throws -> ()) throws {
                try mayFailBefore()
                try closure()
                try mayFailAfter()
        }
        let x: Int
        do {
                try f2 {
                        x = try getX()
                        // use x
                }
                // use x
        } catch {
                // can't use x
        }
        // can't use x

To better explain them, let's replace `f1` with `do`, and `f2` with a throwing 
function followed with do:

Rewritten case 2:

        let x: Int
        do {
                do {
                        x = try getX()
                        // use x
                }
                // use x
        } catch {
                // can't use x
        }
        // can't use x

Rewritten case 4:

        let x: Int
        do {
                try mayFail()
                do {
                        x = try getX()
                        // use x
                }
                // use x
        } catch {
                // can't use x
        }
        // can't use x

The examples above are already the behavior of the Swift compiler. I expect 
@noescape(once) closures to behave the same (the cases 2 and 4 above)

> 3) If you consider including this addition to the proposal, it might also 
> help other reviewers if you explained how the compiler will be able to help 
> the programmer write a valid program. E.g. what would the error messages 
> about partially initialised variables look like? And where and when would 
> they appear? Could the compiler suggest certain fixits? Etc.

For error messages about partially initialized variables, we just use the 
regular messages that we already have: `Constant 'x' used before being 
initialized` error.

Gwendal Roué
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to