It's best practice as far as I know to take reference even if owning the parameter is justified because references are often smaller than a struct. But for my example function I'm sure that 60% of the time, primitive types are used in place of my trait, and for primitive types it's best to not take references since their pointers are the same size or sometimes even larger than themselves. So is it possible to make this example function take owned or reference depending on the implementation of my trait?
You can implement MyTrait for references. Say, if you were to implement MyTrait for u32 and for &u32, you could then decide at the callsite if you want to pass &u32 or u32 as T to add.
It already does. A type parameter can stand in for any type. <T: MyTrait> means any type implementing MyTrait; it does not mean "any type implementing MyTraitexcept references".
If you are reading algebra, and you encounter a variable like n in N, you know it means any natural number. It is not "any natural number except those divisible by 3", even though you didn't write it as 3k.
Thank you and very sorry that I left an important part of the explanation out. I need anything that implements my trait to be 'static because it's used in return types
If you need more context here is my actual trait
Note: I'm trying to make it only require Clone and not Copy and I've not been successful yet
They don’t in general, but notice @Jroid8’s original example:
fn add<T: MyTrait>(lhs: T, rhs: T) -> T {
You cannot (in most cases) implement this for T = &U because a new value of type T has to be constructed and returned. This is why the traits like std::ops::Add have a separate associated type for what they return. So, while a ’static bound per se isn’t required, this sort of signature still demands not using references. A different signature will be required to solve the original problem. (I'm not sure exactly what; I haven't previously thought about trying to make generic code that “does the right thing” with passing small values vs. references fully automatically.)
This is my problem exactly. Is there not a way to write the function signature that does the right thing? so I don't have to write the whole function again
Because more than one implementor could write the same generic associated type definition, and the compiler doesn't try to go backwards from associated types to implementors.