I'm not sure I understand the question completely. There are 4 different statements we could be talking about here:
1. if … { … }
2. if let x = … { … }
3. guard … else { … }
4. guard let x = … else { … }
In all 4 cases, there's a new scope inside the braces, which follows the compiler rules for new scopes inside braces. That's not what we're talking about.
In cases 1 and 3, there's no other scoping consideration, and so those cases are not what we're talking about either.
In cases 2 and 4, there's a scope-related side effect, but it's — intentionally — asymmetric. For 'if let', a new uwrapped x is defined inside the braces. For 'guard let', a new uwrapped x is defined for the rest of the current scope, and there's no new definition of x inside the braces. (I checked: if you try to refer to x inside the braces, you get a warning that it's not the x you think it is.)
Case 2 behaves as expected now, because it's always "just" shadowing, as we normally understand it, so it doesn't cause an error when x is a local variable.
Case 3 is weird, because one of three different things can happen (according to the tests I posted earlier):
a. If the original x is a property, the guard's new definition of x "shadows" the property in the rest of the scope
b. If x is a parameter, the new x "redefines" the parameter in the same scope, without an error (surprisingly)
c. If x is a local variable, the new x "redefines" the local variable, and thus produces the error
What I want is for 'guard let' not to produce a redefinition error, ever, so that it's usable in all the same cases as 'if let'. If I've done my accounting properly, that means everything is working reasonably (by my standards), except that case 3c should not produce an error.