5

If I have a long list of type bounds that must be repeated in many places, how can I give them a name?

For example, what if instead of:

fn foo<T: Thing>(t: T) -> T
    where T: Copy, T: Debug { ... }

I want to write:

fn foo<T: Thing>(t: T) -> T
    where T: CopyDebug { ... }

where CopyDebug is defined to be Copy+Debug?

Herohtar
  • 5,347
  • 4
  • 31
  • 41
Max Heiber
  • 14,346
  • 12
  • 59
  • 97

2 Answers2

6

You can combine a list of type bounds into a single trait by creating an empty trait that requires the full list of type bounds on its implementer, like this:

trait MyCombination: A + B + C + D {}
impl<T: A + B + C + D> MyCombination for T {}

So in the case of CopyDebug, you can write:

trait CopyDebug: Copy + Debug {}
impl<T: Copy + Debug> CopyDebug for T {}
Leo
  • 219
  • 1
  • 4
  • 2
    This is the answer I was looking for, but I marked [the answer about nightly](https://stackoverflow.com/a/68575743/2482570) as the selected answer because it may be more useful for Posterity if the feature lands. – Max Heiber Jul 29 '21 at 12:57
6

If you are using nightly Rust, you can use the nightly feature trait_alias (https://doc.rust-lang.org/unstable-book/language-features/trait-alias.html)

trait CopyDebug = Copy + Debug;

And then any type satisfying both Copy and Debug will also satisfy CopyDebug automatically.

Because this feature is nightly, you need to put #![feature(trait_alias)] at the top of your crate main file.

skywalker
  • 1,230
  • 14
  • 30
  • from the docs: `These allow aliases to be created for one or more traits (currently just a single regular trait plus any number of auto-traits)` Thus it cannot be used with *any* number of traits, but just **one** normal trait and any number of auto-traits – Svetlin Zarev Jul 29 '21 at 12:30
  • Strange, because it works... (https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=691b2554c05e45f307565fd96a0c0e56) Maybe the docs are outdated? @SvetlinZarev – skywalker Jul 29 '21 at 12:53