Generic trait auto distiguish

No, the ~const does not mean !const. Instead it’s an (unstable, not finalized) syntax used in trait bounds on const fn where something like

const fn foo<T: ~const Bar>(…) {…} 

means

  • when calling foo normally, you’ll need to ensure T: Bar
  • when calling foo in a const context (e.g. as an initializer to a static or in the definition of a const), you’ll have to ensure T: const Bar
    • note, that T: const Bar means that there’s not only an impl Bar for T but an impl const Bar for T, the latter containing all the same methods of Bar, but as const fns, instead of ordinary fns.

More information: Pre-RFC: Revamped const_trait_impl aka RFC 2632

So the ~ is not negation, instead it’s deliberately new (and, as mentioned, WIP/unstable/nonfinal) syntax with a very specific meaning.


The related question of whether something like

struct Foo<T> {
  val: T,
}

impl<T: Copy> Foo<T> {
  fn foo(&self) {
    println!("copy");
  }
}

impl<T: !Copy> Foo<T> {
  fn foo(&self) {
    println!("no copy");
  }
}

might ever work: answer is, yes probably at some point in the (possibly distant) future for certain traits and/or types negative trait bounds will be supported in rust; but not like this particular example for the trait Copy and generically over all types. The reason is: It’s currently an accepted change to add an implementation of Copy to a type over a minor semver-change. Anything that relies on T: !Copy would break over such a change. Of course, this particular example does not just have an impl based on T: !Copy, so it doesn’t fully break; changing behavior based on trait implementations is something that the WIP language feature “specialization” tackles – it does use different syntax and has lots of unresolved problems, but can essentially achieve the same thing.

2 Likes