Skip to content

Commit 896d743

Browse files
committed
Minor changes from PR feedback
1 parent 51e8878 commit 896d743

File tree

4 files changed

+45
-42
lines changed

4 files changed

+45
-42
lines changed

clippy_lints/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,8 +2145,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
21452145
store.register_late_pass(move || Box::new(feature_name::FeatureName));
21462146
store.register_late_pass(move || Box::new(iter_not_returning_iterator::IterNotReturningIterator));
21472147
store.register_late_pass(move || Box::new(if_then_panic::IfThenPanic));
2148-
let enable_raw_pointer_heuristic = conf.enable_raw_pointer_heuristic;
2149-
store.register_late_pass(move || Box::new(non_send_field_in_send_ty::NonSendFieldInSendTy::new(enable_raw_pointer_heuristic)));
2148+
let enable_raw_pointer_heuristic_for_send = conf.enable_raw_pointer_heuristic_for_send;
2149+
store.register_late_pass(move || Box::new(non_send_field_in_send_ty::NonSendFieldInSendTy::new(enable_raw_pointer_heuristic_for_send)));
21502150
}
21512151

21522152
#[rustfmt::skip]

clippy_lints/src/non_send_field_in_send_ty.rs

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ declare_clippy_lint! {
4242
/// unsafe impl<T> Send for ExampleStruct<T> {}
4343
/// ```
4444
/// Use thread-safe types like [`std::sync::Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html)
45-
/// and specify correct bounds on generic type parameters (`T: Send`).
45+
/// or specify correct bounds on generic type parameters (`T: Send`).
4646
pub NON_SEND_FIELD_IN_SEND_TY,
4747
nursery,
4848
"there is field that does not implement `Send` in a `Send` struct"
@@ -125,7 +125,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
125125
for field in non_send_fields {
126126
diag.span_note(
127127
field.span,
128-
&format!("the field `{}` has type `{}` which is not `Send`", field.name, field.ty),
128+
&format!("the field `{}` has type `{}` which is `!Send`", field.name, field.ty),
129129
);
130130

131131
match field.generic_params.len() {
@@ -165,7 +165,7 @@ impl<'tcx> NonSendField<'tcx> {
165165
}
166166

167167
/// Given a type, collect all of its generic parameters.
168-
/// Example: MyStruct<P, Box<Q, R>> => vec![P, Q, R]
168+
/// Example: `MyStruct<P, Box<Q, R>>` => `vec![P, Q, R]`
169169
fn collect_generic_params<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Vec<Ty<'tcx>> {
170170
ty.walk(cx.tcx)
171171
.filter_map(|inner| match inner.unpack() {
@@ -184,31 +184,34 @@ fn ty_implements_send_or_copy(cx: &LateContext<'tcx>, ty: Ty<'tcx>, send_trait:
184184
/// Heuristic to allow cases like `Vec<*const u8>`
185185
fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, send_trait: DefId) -> bool {
186186
if ty_implements_send_or_copy(cx, ty, send_trait) {
187-
true
188-
} else {
189-
// The type is known to be `!Send` and `!Copy`
190-
match ty.kind() {
191-
ty::Tuple(_) => ty
192-
.tuple_fields()
193-
.all(|ty| ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait)),
194-
ty::Array(ty, _) | ty::Slice(ty) => ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait),
195-
ty::Adt(_, substs) => {
196-
if contains_raw_pointer(cx, ty) {
197-
// descends only if ADT contains any raw pointers
198-
substs.iter().all(|generic_arg| match generic_arg.unpack() {
199-
GenericArgKind::Type(ty) => ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait),
200-
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => true,
201-
})
202-
} else {
203-
false
204-
}
205-
},
206-
ty::RawPtr(_) => true,
207-
_ => false,
208-
}
187+
return true;
188+
}
189+
190+
// The type is known to be `!Send` and `!Copy`
191+
match ty.kind() {
192+
ty::Tuple(_) => ty
193+
.tuple_fields()
194+
.all(|ty| ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait)),
195+
ty::Array(ty, _) | ty::Slice(ty) => ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait),
196+
ty::Adt(_, substs) => {
197+
if contains_raw_pointer(cx, ty) {
198+
// descends only if ADT contains any raw pointers
199+
substs.iter().all(|generic_arg| match generic_arg.unpack() {
200+
GenericArgKind::Type(ty) => ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait),
201+
// Lifetimes and const generics are not solid part of ADT and ignored
202+
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => true,
203+
})
204+
} else {
205+
false
206+
}
207+
},
208+
// Raw pointers are `!Send` but allowed by the heuristic
209+
ty::RawPtr(_) => true,
210+
_ => false,
209211
}
210212
}
211213

214+
/// Checks if the type contains any raw pointers in substs (including nested ones).
212215
fn contains_raw_pointer<'tcx>(cx: &LateContext<'tcx>, target_ty: Ty<'tcx>) -> bool {
213216
for ty_node in target_ty.walk(cx.tcx) {
214217
if_chain! {

clippy_lints/src/utils/conf.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ define_Conf! {
287287
/// Lint: NON_SEND_FIELD_IN_SEND_TY.
288288
///
289289
/// Whether to apply the raw pointer heuristic in `non_send_field_in_send_ty` lint.
290-
(enable_raw_pointer_heuristic: bool = true),
290+
(enable_raw_pointer_heuristic_for_send: bool = true),
291291
}
292292

293293
/// Search for the configuration file.

tests/ui/non_send_field_in_send_ty.stderr

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | unsafe impl<T> Send for RingBuffer<T> {}
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
= note: `-D clippy::non-send-field-in-send-ty` implied by `-D warnings`
8-
note: the field `data` has type `std::vec::Vec<std::cell::UnsafeCell<T>>` which is not `Send`
8+
note: the field `data` has type `std::vec::Vec<std::cell::UnsafeCell<T>>` which is `!Send`
99
--> $DIR/non_send_field_in_send_ty.rs:11:5
1010
|
1111
LL | data: Vec<UnsafeCell<T>>,
@@ -18,7 +18,7 @@ error: this implementation is unsound, as some fields in `MvccRwLock<T>` are `!S
1818
LL | unsafe impl<T> Send for MvccRwLock<T> {}
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2020
|
21-
note: the field `lock` has type `std::sync::Mutex<std::boxed::Box<T>>` which is not `Send`
21+
note: the field `lock` has type `std::sync::Mutex<std::boxed::Box<T>>` which is `!Send`
2222
--> $DIR/non_send_field_in_send_ty.rs:21:5
2323
|
2424
LL | lock: Mutex<Box<T>>,
@@ -31,7 +31,7 @@ error: this implementation is unsound, as some fields in `ArcGuard<RC, T>` are `
3131
LL | unsafe impl<RC, T: Send> Send for ArcGuard<RC, T> {}
3232
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3333
|
34-
note: the field `head` has type `std::sync::Arc<RC>` which is not `Send`
34+
note: the field `head` has type `std::sync::Arc<RC>` which is `!Send`
3535
--> $DIR/non_send_field_in_send_ty.rs:29:5
3636
|
3737
LL | head: Arc<RC>,
@@ -44,7 +44,7 @@ error: this implementation is unsound, as some fields in `DeviceHandle<T>` are `
4444
LL | unsafe impl<T: UsbContext> Send for DeviceHandle<T> {}
4545
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4646
|
47-
note: the field `context` has type `T` which is not `Send`
47+
note: the field `context` has type `T` which is `!Send`
4848
--> $DIR/non_send_field_in_send_ty.rs:44:5
4949
|
5050
LL | context: T,
@@ -57,7 +57,7 @@ error: this implementation is unsound, as some fields in `NoGeneric` are `!Send`
5757
LL | unsafe impl Send for NoGeneric {}
5858
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5959
|
60-
note: the field `rc_is_not_send` has type `std::rc::Rc<std::string::String>` which is not `Send`
60+
note: the field `rc_is_not_send` has type `std::rc::Rc<std::string::String>` which is `!Send`
6161
--> $DIR/non_send_field_in_send_ty.rs:52:5
6262
|
6363
LL | rc_is_not_send: Rc<String>,
@@ -70,19 +70,19 @@ error: this implementation is unsound, as some fields in `MultiField<T>` are `!S
7070
LL | unsafe impl<T> Send for MultiField<T> {}
7171
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7272
|
73-
note: the field `field1` has type `T` which is not `Send`
73+
note: the field `field1` has type `T` which is `!Send`
7474
--> $DIR/non_send_field_in_send_ty.rs:58:5
7575
|
7676
LL | field1: T,
7777
| ^^^^^^^^^
7878
= help: add `T: Send` bound in `Send` impl
79-
note: the field `field2` has type `T` which is not `Send`
79+
note: the field `field2` has type `T` which is `!Send`
8080
--> $DIR/non_send_field_in_send_ty.rs:59:5
8181
|
8282
LL | field2: T,
8383
| ^^^^^^^^^
8484
= help: add `T: Send` bound in `Send` impl
85-
note: the field `field3` has type `T` which is not `Send`
85+
note: the field `field3` has type `T` which is `!Send`
8686
--> $DIR/non_send_field_in_send_ty.rs:60:5
8787
|
8888
LL | field3: T,
@@ -95,7 +95,7 @@ error: this implementation is unsound, as some fields in `MyOption<T>` are `!Sen
9595
LL | unsafe impl<T> Send for MyOption<T> {}
9696
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9797
|
98-
note: the field `0` has type `T` which is not `Send`
98+
note: the field `0` has type `T` which is `!Send`
9999
--> $DIR/non_send_field_in_send_ty.rs:66:12
100100
|
101101
LL | MySome(T),
@@ -108,7 +108,7 @@ error: this implementation is unsound, as some fields in `MultiParam<A, B>` are
108108
LL | unsafe impl<A, B> Send for MultiParam<A, B> {}
109109
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
110110
|
111-
note: the field `vec` has type `std::vec::Vec<(A, B)>` which is not `Send`
111+
note: the field `vec` has type `std::vec::Vec<(A, B)>` which is `!Send`
112112
--> $DIR/non_send_field_in_send_ty.rs:74:5
113113
|
114114
LL | vec: Vec<(A, B)>,
@@ -121,7 +121,7 @@ error: this implementation is unsound, as some fields in `HeuristicTest` are `!S
121121
LL | unsafe impl Send for HeuristicTest {}
122122
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
123123
|
124-
note: the field `field4` has type `(*const NonSend, std::rc::Rc<u8>)` which is not `Send`
124+
note: the field `field4` has type `(*const NonSend, std::rc::Rc<u8>)` which is `!Send`
125125
--> $DIR/non_send_field_in_send_ty.rs:90:5
126126
|
127127
LL | field4: (*const NonSend, Rc<u8>),
@@ -134,7 +134,7 @@ error: this implementation is unsound, as some fields in `AttrTest3<T>` are `!Se
134134
LL | unsafe impl<T> Send for AttrTest3<T> {}
135135
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
136136
|
137-
note: the field `0` has type `T` which is not `Send`
137+
note: the field `0` has type `T` which is `!Send`
138138
--> $DIR/non_send_field_in_send_ty.rs:109:11
139139
|
140140
LL | Enum2(T),
@@ -147,7 +147,7 @@ error: this implementation is unsound, as some fields in `Complex<P, u32>` are `
147147
LL | unsafe impl<P> Send for Complex<P, u32> {}
148148
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
149149
|
150-
note: the field `field1` has type `P` which is not `Send`
150+
note: the field `field1` has type `P` which is `!Send`
151151
--> $DIR/non_send_field_in_send_ty.rs:118:5
152152
|
153153
LL | field1: A,
@@ -160,7 +160,7 @@ error: this implementation is unsound, as some fields in `Complex<Q, std::sync::
160160
LL | unsafe impl<Q: Send> Send for Complex<Q, MutexGuard<'static, bool>> {}
161161
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
162162
|
163-
note: the field `field2` has type `std::sync::MutexGuard<'static, bool>` which is not `Send`
163+
note: the field `field2` has type `std::sync::MutexGuard<'static, bool>` which is `!Send`
164164
--> $DIR/non_send_field_in_send_ty.rs:119:5
165165
|
166166
LL | field2: B,

0 commit comments

Comments
 (0)