They are not completely equivalent. impl Trait in argument position cannot be explicitly instantiated, i.e. do_something::<i64>(0) doesn't work with it.
IMO argument position impl Trait has really no added value. There's nothing it can do that already-existing generic syntax couldn't, but the converse is true, so it's strictly less useful than explicit generics.
The conventional wisdom behind allowing it in argument position was that "it's consistent", but that seems misguided because it's not even allowed in return position of trait methods, nor is it allowed in a ton of other places, for instance you can't make an impl Trait-typed variable.
The impl Trait syntax is more "plain English" so to speak, as it tells you exactly what it is doing. It is taking as an argument anything that implements Trait. In that way I like it. On the other side, it is hiding more of what it is doing under-the-hood which can make things more confusing when you happen to get mixed up in what is actually happening for some reason.
That is kind of the nature of what Rust does all over the place. It elides lifetimes, it automatically dereferences pointers. Even when you do fn do_something<T>(hello: T) it is implied that T: Sized.
It is a difficult balancing act between hiding details to make it more readable, and showing details to avoid confusion when the details do matter.
i like impl X syntax, it's just that, given that there's two almost equivalent constructs, of which one is a little more powerful (allowing for the turbofish syntax), it suddenly feels like using it is just laziness and a little more typing with <T: Write> gives users of the function more flexibility