Exhaustive switching with optionals

why does this work:

func foo<T, U>(_ bar1:T?, _ bar2:U?) 
{
    switch (bar1, bar2) 
    { 
    case (let a?, let b?):
        print(a, b) 
    case (let a?, nil): 
        print(a, -1) 
    case(nil, let b?):
        print(-1, b) 
    case (nil, nil): 
        print("") 
    } 
}

foo(Optional<Int>(1), Optional<(Int, Int)>((5, 6)))

but not this?

switch (Optional<Int>(1), Optional<(Int, Int)>((5, 6))) 
{ 
case (let a?, let b?):
    print(a, b) 
case (let a?, nil): 
    print(a, -1) 
case(nil, let b?):
    print(-1, b) 
case (nil, nil): 
    print("") 
} 
error: switch must be exhaustive
switch (Optional<Int>(1), Optional<(Int, Int)>((5, 6))) 
^
note: add missing case: '(_, .some(_, _))'
switch (Optional<Int>(1), Optional<(Int, Int)>((5, 6))) 

Looks like a bug to me, please file.

1 Like

Extra data point: Adding these two cases makes it compile.

switch (Optional<Int>(1), Optional<(Int, Int)>((5, 6))) { 
case (let a?, let b?):	print( a,  b) 
case (let a?,    nil):	print( a, -1) 
case (   nil, let b?):	print(-1,  b) 
case (   nil,    nil):	print("") 

// Add these cases:
case (  nil, let (b, c)?):	print(-1, b, c)
case (let a, let (b, c)?):	print( a, b, c)
} 

FYI you can factor out repeated let keywords:

switch (Optional<Int>(1), Optional<(Int, Int)>((5, 6))) { 
case let ( a?,  b?):	print(a, b) 
case let ( a?, nil):	print(a, -1) 
case let (nil,  b?):	print(-1, b) 
case let (nil, nil):	print("") 

// Add these cases:
case let (nil, (b, c)?):	print(-1, b, c)
case let (  a, (b, c)?):	print(a, b, c)
}
2 Likes