3

I know that I can have functions accept only types that implement a given trait. For example, I can

fn f<T>()
where
    T: MyTrait,
{
    // Super useful stuff
}

What if I wanted to implement a function that accepts anything that does not implement a given trait? For example, say that I have some computation that either:

  • Requires some known, lengthy preprocessing, or
  • Has a specific way of short-cutting through that preprocessing.

What I would like to do is something like:

fn preprocess<T>(computation: &mut T)
where
    T: !Shortcut,
{
    // Carry out the expensive precomputation.
}

I tried figuring out how to work around this problem, but I don't seem to be able to figure out any solution.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Matteo Monti
  • 8,362
  • 19
  • 68
  • 114
  • It looks like this is not available right now in Rust. There is [active discussion](https://github.com/rust-lang/rfcs/issues/1053) on the repo about it, but no commitment so far. The term you're looking for is "negative trait bounds". – Silvio Mayolo Apr 08 '19 at 01:23
  • Instead of a Shortcut trait, have a compilation interface which implements `preprocess` and the rest of the compilation process. Those which do not need preprocessing can implement an empty function. This is an OO approach rather than a procedural approach, you're asking the thing to do its own preprocessing. – Schwern Apr 08 '19 at 01:30

1 Answers1

5

No, you cannot.

Instead, you can use the unstable specialization feature the other way, to opt-in to more efficient processing:

#![feature(specialization)]

trait Process {
    fn process(self);
}

trait Short {}

impl Short for i32 {}

impl<T> Process for T
where
    T: std::fmt::Debug,
{
    default fn process(self) {
        println!("Processing {:?}", self)
    }
}

impl<T> Process for T
where
    T: std::fmt::Debug + Short,
{
    fn process(self) {
        println!("Shortcut {:?}", self)
    }
}

fn main() {
    42i32.process();
    vec![1, 2, 3].process();
}
Shortcut 42
Processing [1, 2, 3]

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366