30

I found in the library reference for std::rc::Rc this trait implementation

impl<T> !Send for Rc<T> 
where
    T: ?Sized, 

What does the exclamation point in front of Send mean?

I consulted both The Rust Programming Language¹ book and The Rust Reference², but didn't find an explanation. Please give a reference in your answer.


¹ especially the [section 3.19 Traits
² and sections 5.1 Traits and 5.1 Implementations
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
nalply
  • 26,770
  • 15
  • 78
  • 101

3 Answers3

34

It's a negative trait implementation for the Send trait as described in RFC 19.

As a summary: The Send trait is an auto trait, which means it is automatically implemented for all types that only contain other Send types:

unsafe auto trait Send {}

(Send is also an unsafe trait, which means it is unsafe to implement, but that is not relevant to the question.)

An auto trait may not define any methods, which also makes it a marker trait. (The syntax for defining auto traits is currently only available in the standard library or on the nightly compiler, but their semantics are stable.)

To opt out of the automatic implementation of Send, you must write an explicit negative trait implementation:

impl !Send for MyType {}

This means that even though MyType only contains other types that are Send, MyType itself will not automatically implement Send.

See also the answer to another question: What is an auto trait in Rust?

trent
  • 25,033
  • 7
  • 51
  • 90
nalply
  • 26,770
  • 15
  • 78
  • 101
  • 1
    @mrnateriver I just reviewed your edit and decided to keep the old syntax, but add the new syntax, as it is still experimental. Take a look and let me know if anything is missing/ wrong – MindSwipe Dec 04 '19 at 09:49
  • 1
    @MindSwipe sure, no problem. AFAI understand, this syntax is experimental for users, but it's used in `stdlib` without any attributes. But anyway, I've started learning Rust just a week ago and I'm still struggling to wrap my head around all the RFCs, experimental features, what's stable and what's not – mrnateriver Dec 04 '19 at 10:28
  • The "new" syntax is still nightly-only, but the old syntax is obsolete, so I have updated the question (again) to avoid misleading new readers, as well as correcting the semantics of auto trait implementation. – trent Dec 04 '19 at 17:30
  • I made this answer community wiki, thank you for the collaboration. – nalply Dec 04 '19 at 18:10
11

This is a negative trait impl, so you can read it as opting out of the Send trait.

fjh
  • 12,121
  • 4
  • 46
  • 46
0

From reference about auto traits:

Auto traits can also have negative implementations, shown as impl !AutoTrait for T in the standard library documentation, that override the automatic implementations. For example *mut T has a negative implementation of Send, and so *mut T is not Send, even if T is.

mdmundo
  • 1,988
  • 2
  • 23
  • 37