| Sort of. Given an instance (can even be a primitive) you can obtain a dyn reference to a trait it implements simply by casting it. let a: i32 = 12 let b = &a as &dyn std::string::ToString; // i32 implements the ToString trait let c = a.to_string(); // Static dispatch let d = b.to_string(); // Dynamic dispatch through dyn reference Note that there's not really any polymorphic objects in rust. All polymorphism in this case goes through the dyn reference which contains a pointer to a vtable for a specific trait. Additionally, going from a dyn reference to a type-specific reference is not easy. Also, certain methods and traits are not dyn-compatible, mostly due to generic parameters. The main use comes in with various libraries. Doing dynamic dispatch on a specific type is not very useful, but your library might expose a trait which you then call some methods on. If you accept a generic parameter (eg. impl Trait) each such invocation will cause monomorphization (the function body is compiled separately for each generic type combination). This can obviously bloat compile times. Using a dyn reference in your API will result in only a single version being compiled. The downside is the inability to inline or optimize based on the type. One additional use I found is that you can sometimes get around the divergent expression type in match expressions. Say you need to print out some values of different types: let value: &dyn Display = match foo {
A(numeric_id) => &numeric_id,
B(string_name) => &string_name,
C => &"static str",
}; This would not work without dyn as each value has a different type. |
Does this mean that the Rust frontend is spitting out the intermediate representation such that it doesn't allow the de-duplication at the linking phase? I see that Rust now has its own linker as of Sep 25' but it still works with normal linkers that are used in C and C++ too - gnu ld, lld, mold, ...