summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.rs
blob: 514fb25c8cfd823bfacd62b2babbfcd3d05e2a22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#![warn(clippy::non_send_fields_in_send_ty)]
#![allow(suspicious_auto_trait_impls)]
#![feature(extern_types)]

use std::cell::UnsafeCell;
use std::ptr::NonNull;
use std::rc::Rc;
use std::sync::{Arc, Mutex, MutexGuard};

// disrustor / RUSTSEC-2020-0150
pub struct RingBuffer<T> {
    data: Vec<UnsafeCell<T>>,
    capacity: usize,
    mask: usize,
}

unsafe impl<T> Send for RingBuffer<T> {}

// noise_search / RUSTSEC-2020-0141
pub struct MvccRwLock<T> {
    raw: *const T,
    lock: Mutex<Box<T>>,
}

unsafe impl<T> Send for MvccRwLock<T> {}

// async-coap / RUSTSEC-2020-0124
pub struct ArcGuard<RC, T> {
    inner: T,
    head: Arc<RC>,
}

unsafe impl<RC, T: Send> Send for ArcGuard<RC, T> {}

// rusb / RUSTSEC-2020-0098
extern "C" {
    type libusb_device_handle;
}

pub trait UsbContext {
    // some user trait that does not guarantee `Send`
}

pub struct DeviceHandle<T: UsbContext> {
    context: T,
    handle: NonNull<libusb_device_handle>,
}

unsafe impl<T: UsbContext> Send for DeviceHandle<T> {}

// Other basic tests
pub struct NoGeneric {
    rc_is_not_send: Rc<String>,
}

unsafe impl Send for NoGeneric {}

pub struct MultiField<T> {
    field1: T,
    field2: T,
    field3: T,
}

unsafe impl<T> Send for MultiField<T> {}

pub enum MyOption<T> {
    MySome(T),
    MyNone,
}

unsafe impl<T> Send for MyOption<T> {}

// Test types that contain `NonNull` instead of raw pointers (#8045)
pub struct WrappedNonNull(UnsafeCell<NonNull<()>>);

unsafe impl Send for WrappedNonNull {}

// Multiple type parameters
pub struct MultiParam<A, B> {
    vec: Vec<(A, B)>,
}

unsafe impl<A, B> Send for MultiParam<A, B> {}

// Tests for raw pointer heuristic
extern "C" {
    type NonSend;
}

pub struct HeuristicTest {
    // raw pointers are allowed
    field1: Vec<*const NonSend>,
    field2: [*const NonSend; 3],
    field3: (*const NonSend, *const NonSend, *const NonSend),
    // not allowed when it contains concrete `!Send` field
    field4: (*const NonSend, Rc<u8>),
    // nested raw pointer is also allowed
    field5: Vec<Vec<*const NonSend>>,
}

unsafe impl Send for HeuristicTest {}

// Test attributes
#[allow(clippy::non_send_fields_in_send_ty)]
pub struct AttrTest1<T>(T);

pub struct AttrTest2<T> {
    #[allow(clippy::non_send_fields_in_send_ty)]
    field: T,
}

pub enum AttrTest3<T> {
    #[allow(clippy::non_send_fields_in_send_ty)]
    Enum1(T),
    Enum2(T),
}

unsafe impl<T> Send for AttrTest1<T> {}
unsafe impl<T> Send for AttrTest2<T> {}
unsafe impl<T> Send for AttrTest3<T> {}

// Multiple non-overlapping `Send` for a single type
pub struct Complex<A, B> {
    field1: A,
    field2: B,
}

unsafe impl<P> Send for Complex<P, u32> {}

// `MutexGuard` is non-Send
unsafe impl<Q: Send> Send for Complex<Q, MutexGuard<'static, bool>> {}

fn main() {}