There are two ways of being polymorphic over traits in Rust, using static dispatch or boxed traits.
Static Dispatch is very analogous to C++ templates (with the as of yet not included in the standard "Concepts" as Traits), so you get a copy of the function specialized for each type. (We get nicer error messages than templates in C++ because we require you to declare up front what methods you are expecting the type to have at function definition time instead of checking at specialization time that everything is defined.) There is no runtime cost to using a statically dispatched trait over a hand specialized version of the function.
The other method, boxed traits, is very similar to vtables. It has some runtime overhead, since the size of the time is not known, you must have a pointer to it (hence "boxed"). I think Rust currently uses fat pointers for this, that is a pair of pointers, one to the object, and the other to the vtable, since you can add new instances to types in other crates, so it'd be tricky to have a complete vtable for all methods of all the traits the type implements in one place.
[0] I'm not that great at Rust, so if there's some hidden cost to this beyond just the conversion methods themselves, someone please correct me.