Skip to content

Commit cdf9a28

Browse files
committed
Improve lint message of await_holding_*
Improves the message of the lints await_holding_lock and await_holding_refcell_ref. Now also actually tests RwLock.
1 parent 668b3e4 commit cdf9a28

File tree

4 files changed

+114
-37
lines changed

4 files changed

+114
-37
lines changed

clippy_lints/src/await_holding_invalid.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use clippy_utils::diagnostics::span_lint_and_note;
1+
use clippy_utils::diagnostics::span_lint_and_then;
22
use clippy_utils::{match_def_path, paths};
33
use rustc_hir::def_id::DefId;
44
use rustc_hir::{AsyncGeneratorKind, Body, BodyId, GeneratorKind};
@@ -118,23 +118,36 @@ fn check_interior_types(cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorType
118118
for ty_cause in ty_causes {
119119
if let rustc_middle::ty::Adt(adt, _) = ty_cause.ty.kind() {
120120
if is_mutex_guard(cx, adt.did) {
121-
span_lint_and_note(
121+
span_lint_and_then(
122122
cx,
123123
AWAIT_HOLDING_LOCK,
124124
ty_cause.span,
125-
"this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await",
126-
ty_cause.scope_span.or(Some(span)),
127-
"these are all the await points this lock is held through",
125+
"this `MutexGuard` is held across an `await` point",
126+
|diag| {
127+
diag.help(
128+
"consider using an async-aware `Mutex` type or ensuring the \
129+
`MutexGuard` is dropped before calling await",
130+
);
131+
diag.span_note(
132+
ty_cause.scope_span.unwrap_or(span),
133+
"these are all the `await` points this lock is held through",
134+
);
135+
},
128136
);
129137
}
130138
if is_refcell_ref(cx, adt.did) {
131-
span_lint_and_note(
139+
span_lint_and_then(
132140
cx,
133141
AWAIT_HOLDING_REFCELL_REF,
134142
ty_cause.span,
135-
"this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await",
136-
ty_cause.scope_span.or(Some(span)),
137-
"these are all the await points this ref is held through",
143+
"this `RefCell` reference is held across an `await` point",
144+
|diag| {
145+
diag.help("ensure the reference is dropped before calling `await`");
146+
diag.span_note(
147+
ty_cause.scope_span.unwrap_or(span),
148+
"these are all the `await` points this reference is held through",
149+
);
150+
},
138151
);
139152
}
140153
}

tests/ui/await_holding_lock.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![warn(clippy::await_holding_lock)]
22

3-
use std::sync::Mutex;
3+
use std::sync::{Mutex, RwLock};
44

55
async fn bad(x: &Mutex<u32>) -> u32 {
66
let guard = x.lock().unwrap();
@@ -17,6 +17,30 @@ async fn good(x: &Mutex<u32>) -> u32 {
1717
47
1818
}
1919

20+
pub async fn bad_rw(x: &RwLock<u32>) -> u32 {
21+
let guard = x.read().unwrap();
22+
baz().await
23+
}
24+
25+
pub async fn bad_rw_write(x: &RwLock<u32>) -> u32 {
26+
let mut guard = x.write().unwrap();
27+
baz().await
28+
}
29+
30+
pub async fn good_rw(x: &RwLock<u32>) -> u32 {
31+
{
32+
let guard = x.read().unwrap();
33+
let y = *guard + 1;
34+
}
35+
{
36+
let mut guard = x.write().unwrap();
37+
*guard += 1;
38+
}
39+
baz().await;
40+
let guard = x.read().unwrap();
41+
47
42+
}
43+
2044
async fn baz() -> u32 {
2145
42
2246
}

tests/ui/await_holding_lock.stderr

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,58 @@
1-
error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await
1+
error: this `MutexGuard` is held across an `await` point
22
--> $DIR/await_holding_lock.rs:6:9
33
|
44
LL | let guard = x.lock().unwrap();
55
| ^^^^^
66
|
77
= note: `-D clippy::await-holding-lock` implied by `-D warnings`
8-
note: these are all the await points this lock is held through
8+
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
9+
note: these are all the `await` points this lock is held through
910
--> $DIR/await_holding_lock.rs:6:5
1011
|
1112
LL | / let guard = x.lock().unwrap();
1213
LL | | baz().await
1314
LL | | }
1415
| |_^
1516

16-
error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await
17-
--> $DIR/await_holding_lock.rs:27:9
17+
error: this `MutexGuard` is held across an `await` point
18+
--> $DIR/await_holding_lock.rs:21:9
19+
|
20+
LL | let guard = x.read().unwrap();
21+
| ^^^^^
22+
|
23+
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
24+
note: these are all the `await` points this lock is held through
25+
--> $DIR/await_holding_lock.rs:21:5
26+
|
27+
LL | / let guard = x.read().unwrap();
28+
LL | | baz().await
29+
LL | | }
30+
| |_^
31+
32+
error: this `MutexGuard` is held across an `await` point
33+
--> $DIR/await_holding_lock.rs:26:9
34+
|
35+
LL | let mut guard = x.write().unwrap();
36+
| ^^^^^^^^^
37+
|
38+
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
39+
note: these are all the `await` points this lock is held through
40+
--> $DIR/await_holding_lock.rs:26:5
41+
|
42+
LL | / let mut guard = x.write().unwrap();
43+
LL | | baz().await
44+
LL | | }
45+
| |_^
46+
47+
error: this `MutexGuard` is held across an `await` point
48+
--> $DIR/await_holding_lock.rs:51:9
1849
|
1950
LL | let guard = x.lock().unwrap();
2051
| ^^^^^
2152
|
22-
note: these are all the await points this lock is held through
23-
--> $DIR/await_holding_lock.rs:27:5
53+
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
54+
note: these are all the `await` points this lock is held through
55+
--> $DIR/await_holding_lock.rs:51:5
2456
|
2557
LL | / let guard = x.lock().unwrap();
2658
LL | |
@@ -31,33 +63,35 @@ LL | | first + second + third
3163
LL | | }
3264
| |_^
3365

34-
error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await
35-
--> $DIR/await_holding_lock.rs:40:13
66+
error: this `MutexGuard` is held across an `await` point
67+
--> $DIR/await_holding_lock.rs:64:13
3668
|
3769
LL | let guard = x.lock().unwrap();
3870
| ^^^^^
3971
|
40-
note: these are all the await points this lock is held through
41-
--> $DIR/await_holding_lock.rs:40:9
72+
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
73+
note: these are all the `await` points this lock is held through
74+
--> $DIR/await_holding_lock.rs:64:9
4275
|
4376
LL | / let guard = x.lock().unwrap();
4477
LL | | baz().await
4578
LL | | };
4679
| |_____^
4780

48-
error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await
49-
--> $DIR/await_holding_lock.rs:52:13
81+
error: this `MutexGuard` is held across an `await` point
82+
--> $DIR/await_holding_lock.rs:76:13
5083
|
5184
LL | let guard = x.lock().unwrap();
5285
| ^^^^^
5386
|
54-
note: these are all the await points this lock is held through
55-
--> $DIR/await_holding_lock.rs:52:9
87+
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
88+
note: these are all the `await` points this lock is held through
89+
--> $DIR/await_holding_lock.rs:76:9
5690
|
5791
LL | / let guard = x.lock().unwrap();
5892
LL | | baz().await
5993
LL | | }
6094
| |_____^
6195

62-
error: aborting due to 4 previous errors
96+
error: aborting due to 6 previous errors
6397

tests/ui/await_holding_refcell_ref.stderr

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,42 @@
1-
error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await
1+
error: this `RefCell` reference is held across an `await` point
22
--> $DIR/await_holding_refcell_ref.rs:6:9
33
|
44
LL | let b = x.borrow();
55
| ^
66
|
77
= note: `-D clippy::await-holding-refcell-ref` implied by `-D warnings`
8-
note: these are all the await points this ref is held through
8+
= help: ensure the reference is dropped before calling `await`
9+
note: these are all the `await` points this reference is held through
910
--> $DIR/await_holding_refcell_ref.rs:6:5
1011
|
1112
LL | / let b = x.borrow();
1213
LL | | baz().await
1314
LL | | }
1415
| |_^
1516

16-
error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await
17+
error: this `RefCell` reference is held across an `await` point
1718
--> $DIR/await_holding_refcell_ref.rs:11:9
1819
|
1920
LL | let b = x.borrow_mut();
2021
| ^
2122
|
22-
note: these are all the await points this ref is held through
23+
= help: ensure the reference is dropped before calling `await`
24+
note: these are all the `await` points this reference is held through
2325
--> $DIR/await_holding_refcell_ref.rs:11:5
2426
|
2527
LL | / let b = x.borrow_mut();
2628
LL | | baz().await
2729
LL | | }
2830
| |_^
2931

30-
error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await
32+
error: this `RefCell` reference is held across an `await` point
3133
--> $DIR/await_holding_refcell_ref.rs:32:9
3234
|
3335
LL | let b = x.borrow_mut();
3436
| ^
3537
|
36-
note: these are all the await points this ref is held through
38+
= help: ensure the reference is dropped before calling `await`
39+
note: these are all the `await` points this reference is held through
3740
--> $DIR/await_holding_refcell_ref.rs:32:5
3841
|
3942
LL | / let b = x.borrow_mut();
@@ -45,13 +48,14 @@ LL | | first + second + third
4548
LL | | }
4649
| |_^
4750

48-
error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await
51+
error: this `RefCell` reference is held across an `await` point
4952
--> $DIR/await_holding_refcell_ref.rs:44:9
5053
|
5154
LL | let b = x.borrow_mut();
5255
| ^
5356
|
54-
note: these are all the await points this ref is held through
57+
= help: ensure the reference is dropped before calling `await`
58+
note: these are all the `await` points this reference is held through
5559
--> $DIR/await_holding_refcell_ref.rs:44:5
5660
|
5761
LL | / let b = x.borrow_mut();
@@ -63,27 +67,29 @@ LL | | first + second + third
6367
LL | | }
6468
| |_^
6569

66-
error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await
70+
error: this `RefCell` reference is held across an `await` point
6771
--> $DIR/await_holding_refcell_ref.rs:59:13
6872
|
6973
LL | let b = x.borrow_mut();
7074
| ^
7175
|
72-
note: these are all the await points this ref is held through
76+
= help: ensure the reference is dropped before calling `await`
77+
note: these are all the `await` points this reference is held through
7378
--> $DIR/await_holding_refcell_ref.rs:59:9
7479
|
7580
LL | / let b = x.borrow_mut();
7681
LL | | baz().await
7782
LL | | };
7883
| |_____^
7984

80-
error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await
85+
error: this `RefCell` reference is held across an `await` point
8186
--> $DIR/await_holding_refcell_ref.rs:71:13
8287
|
8388
LL | let b = x.borrow_mut();
8489
| ^
8590
|
86-
note: these are all the await points this ref is held through
91+
= help: ensure the reference is dropped before calling `await`
92+
note: these are all the `await` points this reference is held through
8793
--> $DIR/await_holding_refcell_ref.rs:71:9
8894
|
8995
LL | / let b = x.borrow_mut();

0 commit comments

Comments
 (0)