I guess it's a bit a matter of taste, but to me "x: &Foo" seems unambiguously like dynamic dispatch (given that Foo is a trait). The only thing you know about the type of your parameter is that it is an instance of Foo, therefore you need dynamic dispatch, whereas the T: Foo, x: &T reads like "x is of a specific concrete type that's an instance of Foo", which gives you static dispatch.
I think this is informed by the fact that that's what it means today. If Rust didn't have any dynamic dispatch at all, and it was suggested we have this `&Foo` means `&T: Foo` sugar, I can't imagine anyone saying "That syntax looks like dynamic dispatch!" "What dynamic dispatch? Rust doesn't have that feature."
And since users almost never specify the implementing type manually (type inference figures it out with very few exceptions), the whole notion that this is a function parametric over types is obscured for many users.
There are trickier issues though about the fact that in return positions we'd want it to mean something different (existential vs universal), and there are "higher order" positions in which its very difficult to determine which of the two semantics you meant here. This has a resemblance to covariance & countervariance.
Actually, I think that it's because of how each syntax maps to other languages I've used before.
The parametrically polymorphic version reads a lot like Haskell, and both will monomorphise and use static dispatch:
fn doStuff<T: Foo>(x: T) -> T
doStuff :: Foo t => t -> t
Whereas the Trait Object syntax Reminds me more of Java's syntax, and both use dynamic dispatch:
fn doStuff(x: &Foo)
public void doSttuf(Foo x)
I don't think there's anything intrinsic about either syntax that suggests it _must_ use the dispatch style it does, but when I first started learning Rust, these similarities made it click for me which syntax went with what.