let (x: Int, y: String) = (x: 200, y: "Hello world")
print(Int) // prints "200"
print(String) // prints "Hello world"
I know that it should be written let (x, y): (Int, String) = (200, "Hello word"), but why Swift is accepting the pattern (x: Int, y: String) without compilation errors? After the first line, x and y don't exist as variables, where did they go?
x and y aren't variables in this case; they're tuple element labels. So your first line declares two variables: one named Int which will receive the element labeled x on the right-hand side, and one named String which will receive the element labeled y on the right-hand side.
Names can be shadowed in more-local scopes in Swift, so declaring Int and String as variables like this is technically valid, if confusing.
It's easier to see what's going on when you note that you can drop the labels on both sides (or just one side), which leaves you with this:
let (Int, String) = (200, "Hello world")
or if you use different variable names while keeping the labels:
I don't think it's destructuring. Trying something that fits that description is disallowed:
// Compiles without warning:
typealias S = (x: Int, y: Int)
if case let (x: x, y: y) = S(x: 1, y: 2) { }
typealias S = (y: Int, x: Int)
// Expression shuffles the elements of this tuple; this behavior is deprecated
if case let (x: x, y: y) = S(x: 1, y: 2) { }
typealias S = (y: Int, x: Int, z: Int)
// …tuples have a different number of elements
if case let (x: x, y: y) = S(x: 1, y: 2, z: 3) { }