# Generic trait auto distiguish

**URL:** <https://internals.rust-lang.org/t/generic-trait-auto-distiguish/15454>\
**Category:** language design\
**Created:** [October 16, 2021, 3:49pm UTC](https://internals.rust-lang.org/t/generic-trait-auto-distiguish/15454 "2021-10-16T15:49:12Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![al8n](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/al8n/32/8640_2.png) [@al8n](https://internals.rust-lang.org/u/al8n)\
**Post date:** [October 16, 2021, 3:49pm UTC](https://internals.rust-lang.org/t/generic-trait-auto-distiguish/15454/1 "2021-10-16T15:49:12Z")

</div>

Hi, I saw `~` is used for `~const`, so is there any plan to support something like the below piece of code?

```rust
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");
  }
}

```

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [October 16, 2021, 3:53pm UTC](https://internals.rust-lang.org/t/generic-trait-auto-distiguish/15454/2 "2021-10-16T15:53:26Z")

</div>

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

```rust
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 fn`s, instead of ordinary `fn`s.

More information: [Pre-RFC: Revamped const\_trait\_impl aka RFC 2632](https://internals.rust-lang.org/t/pre-rfc-revamped-const-trait-impl-aka-rfc-2632/15192)

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

```rust
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](https://rust-lang.github.io/rfcs/1210-impl-specialization.html)” tackles – it does use different syntax and has lots of unresolved problems, but can essentially [achieve the same thing](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=9dad3121db7356fe9f40b09bb43dddbd).

---

<div class="post-metadata">

**Author:** ![fee1-dead](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/fee1-dead/32/8232_2.png) [@fee1-dead](https://internals.rust-lang.org/u/fee1-dead)\
**Post date:** [October 16, 2021, 4:45pm UTC](https://internals.rust-lang.org/t/generic-trait-auto-distiguish/15454/3 "2021-10-16T16:45:51Z")

</div>

`~const` as a trait bound modifier can be seen like this:

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

```

is _effect_ively:

```rust
constif(C) fn foo<constness C, T: constif(C) Bar>(…) {…} 

```

which expands to two functions with either `constness C` being `const` or not const:

```rust
const fn foo<T: const Bar>(…) {…} // use this one when called from const context
fn foo<T: Bar>(…) {…} // use this one when called at runtime

```

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [October 16, 2021, 9:40pm UTC](https://internals.rust-lang.org/t/generic-trait-auto-distiguish/15454/4 "2021-10-16T21:40:34Z")

</div>

> [@steffahn](#):
>
> whether `impl<T: !Copy> Foo<T>` might ever work

I think there's a couple of ways that this could happen. One interesting one would be for this to only match things for which there's an explicit `impl<T> !Copy for Foo<T> {}` using [negative\_impls - The Rust Unstable Book](https://doc.rust-lang.org/1.55.0/unstable-book/language-features/negative-impls.html).

That would give three categories of things: things which are `Copy` now (and will be in the future unless there's a major version that breaks it), things where are promised that they _won't_ be copy (unless there's a major version that breaks it), and things that haven't made a promise one way or the other yet (for which point neither of those `impl`s would match).

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [January 14, 2022, 9:41pm UTC](https://internals.rust-lang.org/t/generic-trait-auto-distiguish/15454/5 "2022-01-14T21:41:14Z")

</div>

Closed on January 14, 2022, 9:41pm UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
