That’s the point, you can because rust supports intra-scope shadowing.
If it didn’t you’d have to type-erase, or create a new independently-named binding for every step, as you do in e.g. Erlang (can’t say this is / was my favourite feature of the langage).
Yes, the fact that "V = expression" means "if variable V doesn't exist, assign expression's value to it; otherwise compare the expression's value with the value of V and raise exception if they're not equal" is one of my least favourite parts of Erlang.
I semi-regularly introduce local variables named exactly like one of the function's parameter and then spend several minutes trying to understand why the line expression on the right-hand side of assignment throws badmatch: of course, it doesn't, it's the assignment itself that throws it.
Yes that’s also an interesting facet of the language. IIRC it makes sense because of the Prolog ancestry, so it kinda-sorta looks like unification if you squint, but boy is it annoying.