Using a complex generic function as a struct attribute


Hi there, I’m having some issues trying to use a complex function as an attribute in a struct. The function I want to have as an attribute is this:

fn the_fn<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
    input.into() // Example, just to get the header

And I’ve thought of using a Box, but seems difficult to know the type of that attribute. Even if I change the input type to &str (which is possible in my use case) I get issues with lifetime parameters.

Here is the play code:

How can I do it properly?


Unfortunately you can’t because generics don’t exist at runtime. We call this monomorphization. At compile time, rust “instantiates” a concrete copy of every generic function for every set of concrete type arguments used by the program. For example, given:

fn debug<A: Debug>(a: A) {
    println!("{:?}", &a);

fn main() {
    debug("my string");

Rust will instantiate debug::<u32> and debug::<&'static str> but the compiled program won’t know anything about, e.g., debug::<String>.

This is why rust has dynamic dispatch (trait objects, e.g., &Debug). The following program will only instantiate a single debug function.

fn debug(a: &Debug) {
    println!("{:?}", a);

fn main() {
    debug(&"my string");

However, that won’t work in your case because:

  1. Into requires that all types on which it is implemented be Sized. Sized is a marker trait implemented on types whose size is known at compile time. Into imposes this constraint because Into::into takes self by-value (consumes it) and, in today’s rust, there’s no way to take a “dynamically” (known only at runtime) sized type (DST) by value.
  2. Traits bounded by Sized cannot be turned into trait objects because the size of a trait object is not known at compile time.

My explanation of dynamically sized/statically sized types is very light on details so please say so if you’re confused.


OK, I get it, I will use Fn(&str) -> String+ Send + Sync, since it’s OK in my current situation. Thanks for the explanation!