]>
Commit | Line | Data |
---|---|---|
f2b60f7d FG |
1 | ### What it does |
2 | This lint warns about a `Send` implementation for a type that | |
3 | contains fields that are not safe to be sent across threads. | |
4 | It tries to detect fields that can cause a soundness issue | |
5 | when sent to another thread (e.g., `Rc`) while allowing `!Send` fields | |
6 | that are expected to exist in a `Send` type, such as raw pointers. | |
7 | ||
8 | ### Why is this bad? | |
9 | Sending the struct to another thread effectively sends all of its fields, | |
10 | and the fields that do not implement `Send` can lead to soundness bugs | |
11 | such as data races when accessed in a thread | |
12 | that is different from the thread that created it. | |
13 | ||
14 | See: | |
15 | * [*The Rustonomicon* about *Send and Sync*](https://doc.rust-lang.org/nomicon/send-and-sync.html) | |
16 | * [The documentation of `Send`](https://doc.rust-lang.org/std/marker/trait.Send.html) | |
17 | ||
18 | ### Known Problems | |
19 | This lint relies on heuristics to distinguish types that are actually | |
20 | unsafe to be sent across threads and `!Send` types that are expected to | |
21 | exist in `Send` type. Its rule can filter out basic cases such as | |
22 | `Vec<*const T>`, but it's not perfect. Feel free to create an issue if | |
23 | you have a suggestion on how this heuristic can be improved. | |
24 | ||
25 | ### Example | |
26 | ``` | |
27 | struct ExampleStruct<T> { | |
28 | rc_is_not_send: Rc<String>, | |
29 | unbounded_generic_field: T, | |
30 | } | |
31 | ||
32 | // This impl is unsound because it allows sending `!Send` types through `ExampleStruct` | |
33 | unsafe impl<T> Send for ExampleStruct<T> {} | |
34 | ``` | |
35 | Use thread-safe types like [`std::sync::Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html) | |
36 | or specify correct bounds on generic type parameters (`T: Send`). |