3

I've run into a somewhat weird (compile time) error that I cannot make any sense out of. The error is given for the following snippet:

/* error: type 'Int1' does not conform to protocol 'BooleanType' */
let closure1 : (inout foo: Int) -> () = {
    foo -> () in
    (foo<0 ? (foo = -1) : (foo = 1))
}

Error: type 'Int1' does not conform to protocol 'BooleanType'

Note that Int1 is not a typo here.

Question 1: Why am I not allowed to use a single inline if statement (with result '()') as the implicit return type of a void return closure?

Question 2: Out of curiosity, what is the Int1 type? (Curiously enough the same error message, Int1 ... is given even if modifying the closure above to operate on different types in a similar manner).

Why is this of interest for me? I have a few closures that I would like to use in the anonymous form similar of closure1Anon below, but due to this error I can't.

Details and my own (non-fruitful) investigation into the matter follow below.


As described above, the error is prompted when---within a void return closure---using a single inline if statement which includes assignments to an inout parameter.

We can verify that result of an inline statement is the empty tuple value, (), consider e.g.:

var foo = -4
print((foo<0 ? (foo = -1) : (foo = 1)).dynamicType) // ()
print(foo)                                          // -1

... so it should be OK to use as return statement for a void return closure (see e.g. the assignment-followed-by-return example closure4 below).

Below follows the erroneous closure (closure1, closure1Explicit, closure1Anon) as well as five very similar/associated closures that work fine (closure2 through closure7).

/* error: type 'Int1' does not conform to protocol 'BooleanType' */
let closure1 : (inout foo: Int) -> () = {
    foo -> () in
    (foo<0 ? (foo = -1) : (foo = 1))
}

/* same error */
let closure1Explicit : (inout foo: Int) -> () = {
    foo -> () in
    return (foo<0 ? (foo = -1) : (foo = 1))
}

let closure1Anon : (inout foo: Int) -> () = { ($0<0 ? ($0 = -1) : ($0 = 1)) }

Ok:

/* The following are all OK */
let closure2 : (inout foo: Int) -> () = {
    (inout foo: Int) -> () in
    (foo<0 ? (foo = -1) : (foo = 1))
} // thanks @MartinR

let closure3 : (inout foo: Int) -> () = {
    foo -> () in
    let _ = (foo<3 ? (foo = 1) : (foo = 2))
}

let closure4 : (inout foo: Int) -> () = {
    foo -> () in
    (foo<3 ? (foo = 1) : (foo = 2))
    return ()
}

let closure5 : (inout foo: Int) -> () = {
    foo -> () in
    let bar = (foo<3 ? (foo = 1) : (foo = 2))
    return bar
}

/* Error must be related to inout as the two
   following closures works fine */
let closure6 : () -> () = {
    () -> () in
    var a = 0
    return (a<0 ? (a = -1) : (a = 1))
}

var globalVar = 1
let closure7 : () -> () = {
    () -> () in
    (globalVar<0 ? (globalVar = -1) : (globalVar = 1))
}

I can't for the world figure out why closure1/closure1Explicit/closure1Anon above yields this error. Possibly someone can shed some light on this for me?


Final note: the following seemingly similar SO thread seems non-relevant in this case:


I'm using Swift 2.1.1 and Xcode 7.2.1.

5
  • I believe Int1 is actually Builtin.Int1 and comes from the Swift internal type representations linked to LLVM. (I accidentally deleted my previous similar comment, sorry for the double notification...) Commented Feb 3, 2016 at 18:41
  • I've found what I was thinking about: stdlib/public/core github.com/apple/swift/blob/master/stdlib/public/core/… uses Builtin.Int1 to create the Bool datatype. I believe we shouldn't see Int1 in an error message. Commented Feb 3, 2016 at 18:50
  • @EricD. Thanks, that answers my 2nd question, at least. I'll dig into that source code and see if we can at least find out what goes wrong (some boolean init?) Possibly something I should flag as a bug? Commented Feb 3, 2016 at 18:53
  • closure1 compiles if you replace foo -> () in inside the closure by (inout foo: Int) -> () in. I don't why that is necessary in closure1 but not in closure2, 3, ... Commented Feb 3, 2016 at 18:54
  • @MartinR Thanks, I'll add that top the top of the list of working associated closures. (Wont solve, however, the anon. closure case) Commented Feb 3, 2016 at 18:59

1 Answer 1

0

(Adding this thin answer to close the no-longer-relevant question)

The bug described in the question above is no longer present in Swift 2.2 (Xcode 7.3) nor in the Swift 3.0-dev at IBM Sandbox; so the issue seems to have been fixed in with the release of Swift 2.2.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.