Fix doc nits

This commit is contained in:
John Arundel 2024-06-23 12:21:10 +01:00
parent 26c556dd63
commit 625091d236
10 changed files with 163 additions and 156 deletions

View File

@ -11,21 +11,25 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for calls to await while holding a non-async-aware MutexGuard. /// Checks for calls to `await` while holding a non-async-aware
/// `MutexGuard`.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
/// The Mutex types found in std::sync and parking_lot /// The Mutex types found in [`std::sync`] and
/// are not designed to operate in an async context across await points. /// [`parking_lot`](https://docs.rs/parking_lot/latest/parking_lot/) are
/// not designed to operate in an async context across await points.
/// ///
/// There are two potential solutions. One is to use an async-aware Mutex /// There are two potential solutions. One is to use an async-aware `Mutex`
/// type. Many asynchronous foundation crates provide such a Mutex type. The /// type. Many asynchronous foundation crates provide such a `Mutex` type.
/// other solution is to ensure the mutex is unlocked before calling await, /// The other solution is to ensure the mutex is unlocked before calling
/// either by introducing a scope or an explicit call to Drop::drop. /// `await`, either by introducing a scope or an explicit call to
/// [`Drop::drop`].
/// ///
/// ### Known problems /// ### Known problems
/// Will report false positive for explicitly dropped guards /// Will report false positive for explicitly dropped guards
/// ([#6446](https://github.com/rust-lang/rust-clippy/issues/6446)). A workaround for this is /// ([#6446](https://github.com/rust-lang/rust-clippy/issues/6446)). A
/// to wrap the `.lock()` call in a block instead of explicitly dropping the guard. /// workaround for this is to wrap the `.lock()` call in a block instead of
/// explicitly dropping the guard.
/// ///
/// ### Example /// ### Example
/// ```no_run /// ```no_run
@ -73,11 +77,11 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for calls to await while holding a `RefCell` `Ref` or `RefMut`. /// Checks for calls to `await` while holding a `RefCell`, `Ref`, or `RefMut`.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
/// `RefCell` refs only check for exclusive mutable access /// `RefCell` refs only check for exclusive mutable access
/// at runtime. Holding onto a `RefCell` ref across an `await` suspension point /// at runtime. Holding a `RefCell` ref across an await suspension point
/// risks panics from a mutable ref shared while other refs are outstanding. /// risks panics from a mutable ref shared while other refs are outstanding.
/// ///
/// ### Known problems /// ### Known problems
@ -131,13 +135,13 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Allows users to configure types which should not be held across `await` /// Allows users to configure types which should not be held across await
/// suspension points. /// suspension points.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
/// There are some types which are perfectly "safe" to be used concurrently /// There are some types which are perfectly safe to use concurrently from
/// from a memory access perspective but will cause bugs at runtime if they /// a memory access perspective, but that will cause bugs at runtime if
/// are held in such a way. /// they are held in such a way.
/// ///
/// ### Example /// ### Example
/// ///
@ -228,15 +232,15 @@ fn check_interior_types(&self, cx: &LateContext<'_>, coroutine: &CoroutineLayout
cx, cx,
AWAIT_HOLDING_LOCK, AWAIT_HOLDING_LOCK,
ty_cause.source_info.span, ty_cause.source_info.span,
"this `MutexGuard` is held across an `await` point", "this `MutexGuard` is held across an await point",
|diag| { |diag| {
diag.help( diag.help(
"consider using an async-aware `Mutex` type or ensuring the \ "consider using an async-aware `Mutex` type or ensuring the \
`MutexGuard` is dropped before calling await", `MutexGuard` is dropped before calling `await`",
); );
diag.span_note( diag.span_note(
await_points(), await_points(),
"these are all the `await` points this lock is held through", "these are all the await points this lock is held through",
); );
}, },
); );
@ -245,12 +249,12 @@ fn check_interior_types(&self, cx: &LateContext<'_>, coroutine: &CoroutineLayout
cx, cx,
AWAIT_HOLDING_REFCELL_REF, AWAIT_HOLDING_REFCELL_REF,
ty_cause.source_info.span, ty_cause.source_info.span,
"this `RefCell` reference is held across an `await` point", "this `RefCell` reference is held across an await point",
|diag| { |diag| {
diag.help("ensure the reference is dropped before calling `await`"); diag.help("ensure the reference is dropped before calling `await`");
diag.span_note( diag.span_note(
await_points(), await_points(),
"these are all the `await` points this reference is held through", "these are all the await points this reference is held through",
); );
}, },
); );
@ -268,7 +272,7 @@ fn emit_invalid_type(cx: &LateContext<'_>, span: Span, disallowed: &DisallowedPa
AWAIT_HOLDING_INVALID_TYPE, AWAIT_HOLDING_INVALID_TYPE,
span, span,
format!( format!(
"`{}` may not be held across an `await` point per `clippy.toml`", "`{}` may not be held across an await point per `clippy.toml`",
disallowed.path() disallowed.path()
), ),
|diag| { |diag| {

View File

@ -32,7 +32,7 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for casts from any numerical to a float type where /// Checks for casts from any numeric type to a float type where
/// the receiving type cannot store all values from the original type without /// the receiving type cannot store all values from the original type without
/// rounding errors. This possible rounding is to be expected, so this lint is /// rounding errors. This possible rounding is to be expected, so this lint is
/// `Allow` by default. /// `Allow` by default.
@ -58,14 +58,14 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for casts from a signed to an unsigned numerical /// Checks for casts from a signed to an unsigned numeric
/// type. In this case, negative values wrap around to large positive values, /// type. In this case, negative values wrap around to large positive values,
/// which can be quite surprising in practice. However, as the cast works as /// which can be quite surprising in practice. However, since the cast works as
/// defined, this lint is `Allow` by default. /// defined, this lint is `Allow` by default.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
/// Possibly surprising results. You can activate this lint /// Possibly surprising results. You can activate this lint
/// as a one-time check to see where numerical wrapping can arise. /// as a one-time check to see where numeric wrapping can arise.
/// ///
/// ### Example /// ### Example
/// ```no_run /// ```no_run
@ -80,7 +80,7 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for casts between numerical types that may /// Checks for casts between numeric types that may
/// truncate large values. This is expected behavior, so the cast is `Allow` by /// truncate large values. This is expected behavior, so the cast is `Allow` by
/// default. It suggests user either explicitly ignore the lint, /// default. It suggests user either explicitly ignore the lint,
/// or use `try_from()` and handle the truncation, default, or panic explicitly. /// or use `try_from()` and handle the truncation, default, or panic explicitly.
@ -120,17 +120,16 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for casts from an unsigned type to a signed type of /// Checks for casts from an unsigned type to a signed type of
/// the same size, or possibly smaller due to target dependent integers. /// the same size, or possibly smaller due to target-dependent integers.
/// Performing such a cast is a 'no-op' for the compiler, i.e., nothing is /// Performing such a cast is a no-op for the compiler (that is, nothing is
/// changed at the bit level, and the binary representation of the value is /// changed at the bit level), and the binary representation of the value is
/// reinterpreted. This can cause wrapping if the value is too big /// reinterpreted. This can cause wrapping if the value is too big
/// for the target signed type. However, the cast works as defined, so this lint /// for the target signed type. However, the cast works as defined, so this lint
/// is `Allow` by default. /// is `Allow` by default.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
/// While such a cast is not bad in itself, the results can /// While such a cast is not bad in itself, the results can
/// be surprising when this is not the intended behavior, as demonstrated by the /// be surprising when this is not the intended behavior:
/// example below.
/// ///
/// ### Example /// ### Example
/// ```no_run /// ```no_run
@ -144,16 +143,16 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for casts between numerical types that may /// Checks for casts between numeric types that can be replaced by safe
/// be replaced by safe conversion functions. /// conversion functions.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
/// Rust's `as` keyword will perform many kinds of /// Rust's `as` keyword will perform many kinds of conversions, including
/// conversions, including silently lossy conversions. Conversion functions such /// silently lossy conversions. Conversion functions such as `i32::from`
/// as `i32::from` will only perform lossless conversions. Using the conversion /// will only perform lossless conversions. Using the conversion functions
/// functions prevents conversions from turning into silent lossy conversions if /// prevents conversions from becoming silently lossy if the input types
/// the types of the input expressions ever change, and make it easier for /// ever change, and makes it clear for people reading the code that the
/// people reading the code to know that the conversion is lossless. /// conversion is lossless.
/// ///
/// ### Example /// ### Example
/// ```no_run /// ```no_run
@ -177,19 +176,21 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for casts to the same type, casts of int literals to integer types, casts of float /// Checks for casts to the same type, casts of int literals to integer
/// literals to float types and casts between raw pointers without changing type or constness. /// types, casts of float literals to float types, and casts between raw
/// pointers that don't change type or constness.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
/// It's just unnecessary. /// It's just unnecessary.
/// ///
/// ### Known problems /// ### Known problems
/// When the expression on the left is a function call, the lint considers the return type to be /// When the expression on the left is a function call, the lint considers
/// a type alias if it's aliased through a `use` statement /// the return type to be a type alias if it's aliased through a `use`
/// (like `use std::io::Result as IoResult`). It will not lint such cases. /// statement (like `use std::io::Result as IoResult`). It will not lint
/// such cases.
/// ///
/// This check is also rather primitive. It will only work on primitive types without any /// This check will only work on primitive types without any intermediate
/// intermediate references, raw pointers and trait objects may or may not work. /// references: raw pointers and trait objects may or may not work.
/// ///
/// ### Example /// ### Example
/// ```no_run /// ```no_run
@ -211,17 +212,17 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for casts, using `as` or `pointer::cast`, /// Checks for casts, using `as` or `pointer::cast`, from a
/// from a less-strictly-aligned pointer to a more-strictly-aligned pointer /// less strictly aligned pointer to a more strictly aligned pointer.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
/// Dereferencing the resulting pointer may be undefined /// Dereferencing the resulting pointer may be undefined behavior.
/// behavior.
/// ///
/// ### Known problems /// ### Known problems
/// Using `std::ptr::read_unaligned` and `std::ptr::write_unaligned` or similar /// Using [`std::ptr::read_unaligned`] and [`std::ptr::write_unaligned`] or
/// on the resulting pointer is fine. Is over-zealous: Casts with manual alignment checks or casts like /// similar on the resulting pointer is fine. Is over-zealous: casts with
/// u64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis. /// manual alignment checks or casts like `u64` -> `u8` -> `u16` can be
/// fine. Miri is able to do a more in-depth analysis.
/// ///
/// ### Example /// ### Example
/// ```no_run /// ```no_run
@ -234,20 +235,21 @@
#[clippy::version = "pre 1.29.0"] #[clippy::version = "pre 1.29.0"]
pub CAST_PTR_ALIGNMENT, pub CAST_PTR_ALIGNMENT,
pedantic, pedantic,
"cast from a pointer to a more-strictly-aligned pointer" "cast from a pointer to a more strictly aligned pointer"
} }
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for casts of function pointers to something other than usize /// Checks for casts of function pointers to something other than `usize`.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
/// Casting a function pointer to anything other than usize/isize is not portable across /// Casting a function pointer to anything other than `usize`/`isize` is
/// architectures, because you end up losing bits if the target type is too small or end up with a /// not portable across architectures. It either loses bits if the target
/// bunch of extra bits that waste space and add more instructions to the final binary than /// type is too small, or creates extra bits that waste space and bloat the
/// strictly necessary for the problem /// resulting binary.
/// ///
/// Casting to isize also doesn't make sense since there are no signed addresses. /// Casting to `isize` also doesn't make sense, since addresses are never
/// signed.
/// ///
/// ### Example /// ### Example
/// ```no_run /// ```no_run
@ -263,17 +265,17 @@
#[clippy::version = "pre 1.29.0"] #[clippy::version = "pre 1.29.0"]
pub FN_TO_NUMERIC_CAST, pub FN_TO_NUMERIC_CAST,
style, style,
"casting a function pointer to a numeric type other than usize" "casting a function pointer to a numeric type other than `usize`"
} }
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for casts of a function pointer to a numeric type not wide enough to /// Checks for casts of a function pointer to a numeric type not wide enough to
/// store address. /// store an address.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
/// Such a cast discards some bits of the function's address. If this is intended, it would be more /// Such a cast discards some bits of the function's address. If this is intended, it would be more
/// clearly expressed by casting to usize first, then casting the usize to the intended type (with /// clearly expressed by casting to `usize` first, then casting the `usize` to the intended type (with
/// a comment) to perform the truncation. /// a comment) to perform the truncation.
/// ///
/// ### Example /// ### Example
@ -306,7 +308,7 @@
/// ### Why restrict this? /// ### Why restrict this?
/// Casting a function pointer to an integer can have surprising results and can occur /// Casting a function pointer to an integer can have surprising results and can occur
/// accidentally if parentheses are omitted from a function call. If you aren't doing anything /// accidentally if parentheses are omitted from a function call. If you aren't doing anything
/// low-level with function pointers then you can opt-out of casting functions to integers in /// low-level with function pointers then you can opt out of casting functions to integers in
/// order to avoid mistakes. Alternatively, you can use this lint to audit all uses of function /// order to avoid mistakes. Alternatively, you can use this lint to audit all uses of function
/// pointer casts in your code. /// pointer casts in your code.
/// ///
@ -349,8 +351,8 @@
/// ### Why is this bad? /// ### Why is this bad?
/// In general, casting values to smaller types is /// In general, casting values to smaller types is
/// error-prone and should be avoided where possible. In the particular case of /// error-prone and should be avoided where possible. In the particular case of
/// converting a character literal to u8, it is easy to avoid by just using a /// converting a character literal to `u8`, it is easy to avoid by just using a
/// byte literal instead. As an added bonus, `b'a'` is even slightly shorter /// byte literal instead. As an added bonus, `b'a'` is also slightly shorter
/// than `'a' as u8`. /// than `'a' as u8`.
/// ///
/// ### Example /// ### Example
@ -371,12 +373,13 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for `as` casts between raw pointers without changing its mutability, /// Checks for `as` casts on a raw pointer that don't change its
/// namely `*const T` to `*const U` and `*mut T` to `*mut U`. /// mutability, namely `*const T` to `*const U` and `*mut T` to `*mut U`.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
/// Though `as` casts between raw pointers are not terrible, `pointer::cast` is safer because /// Though `as` casts between raw pointers are not terrible,
/// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`. /// `pointer::cast` is safer because it cannot accidentally change the
/// pointer's mutability, nor cast the pointer to other types like `usize`.
/// ///
/// ### Example /// ### Example
/// ```no_run /// ```no_run
@ -395,12 +398,12 @@
#[clippy::version = "1.51.0"] #[clippy::version = "1.51.0"]
pub PTR_AS_PTR, pub PTR_AS_PTR,
pedantic, pedantic,
"casting using `as` from and to raw pointers that doesn't change its mutability, where `pointer::cast` could take the place of `as`" "casting using `as` on a raw pointer that doesn't change its mutability, where `pointer::cast` could take the place of `as`"
} }
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for `as` casts between raw pointers which change its constness, namely `*const T` to /// Checks for `as` casts on a raw pointer that change its constness, namely `*const T` to
/// `*mut T` and `*mut T` to `*const T`. /// `*mut T` and `*mut T` to `*const T`.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
@ -423,12 +426,12 @@
#[clippy::version = "1.72.0"] #[clippy::version = "1.72.0"]
pub PTR_CAST_CONSTNESS, pub PTR_CAST_CONSTNESS,
pedantic, pedantic,
"casting using `as` from and to raw pointers to change constness when specialized methods apply" "casting using `as` on raw pointers to change constness when specialized methods apply"
} }
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for casts from an enum type to an integral type which will definitely truncate the /// Checks for casts from an enum type to an integral type that will definitely truncate the
/// value. /// value.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
@ -442,7 +445,7 @@
#[clippy::version = "1.61.0"] #[clippy::version = "1.61.0"]
pub CAST_ENUM_TRUNCATION, pub CAST_ENUM_TRUNCATION,
suspicious, suspicious,
"casts from an enum type to an integral type which will truncate the value" "casts from an enum type to an integral type that will truncate the value"
} }
declare_clippy_lint! { declare_clippy_lint! {
@ -621,7 +624,7 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for the result of a `&self`-taking `as_ptr` being cast to a mutable pointer /// Checks for the result of a `&self`-taking `as_ptr` being cast to a mutable pointer.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
/// Since `as_ptr` takes a `&self`, the pointer won't have write permissions unless interior /// Since `as_ptr` takes a `&self`, the pointer won't have write permissions unless interior

View File

@ -33,7 +33,7 @@
/// Checks for the usage of the `to_le_bytes` method and/or the function `from_le_bytes`. /// Checks for the usage of the `to_le_bytes` method and/or the function `from_le_bytes`.
/// ///
/// ### Why restrict this? /// ### Why restrict this?
/// To ensure use of big endian or the targets endianness rather than little endian. /// To ensure use of big-endian or the targets endianness rather than little-endian.
/// ///
/// ### Example /// ### Example
/// ```rust,ignore /// ```rust,ignore
@ -51,7 +51,7 @@
/// Checks for the usage of the `to_be_bytes` method and/or the function `from_be_bytes`. /// Checks for the usage of the `to_be_bytes` method and/or the function `from_be_bytes`.
/// ///
/// ### Why restrict this? /// ### Why restrict this?
/// To ensure use of little endian or the targets endianness rather than big endian. /// To ensure use of little-endian or the targets endianness rather than big-endian.
/// ///
/// ### Example /// ### Example
/// ```rust,ignore /// ```rust,ignore

View File

@ -628,12 +628,12 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))` or /// Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))`
/// `_.or_else(|x| Err(y))`. /// or `_.or_else(|x| Err(y))`.
/// ///
/// ### Why is this bad? /// ### Why is this bad?
/// Readability, this can be written more concisely as /// This can be written more concisely as `_.map(|x| y)` or `_.map_err(|x|
/// `_.map(|x| y)` or `_.map_err(|x| y)`. /// y)`.
/// ///
/// ### Example /// ### Example
/// ```no_run /// ```no_run

View File

@ -12,7 +12,7 @@
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// It lints if a struct has two methods with the same name: /// It lints if a struct has two methods with the same name:
/// one from a trait, another not from trait. /// one from a trait, another not from a trait.
/// ///
/// ### Why restrict this? /// ### Why restrict this?
/// Confusing. /// Confusing.

View File

@ -1,4 +1,4 @@
error: `std::string::String` may not be held across an `await` point per `clippy.toml` error: `std::string::String` may not be held across an await point per `clippy.toml`
--> tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs:5:9 --> tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs:5:9
| |
LL | let _x = String::from("hello"); LL | let _x = String::from("hello");
@ -8,13 +8,13 @@ LL | let _x = String::from("hello");
= note: `-D clippy::await-holding-invalid-type` implied by `-D warnings` = note: `-D clippy::await-holding-invalid-type` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::await_holding_invalid_type)]` = help: to override `-D warnings` add `#[allow(clippy::await_holding_invalid_type)]`
error: `std::net::Ipv4Addr` may not be held across an `await` point per `clippy.toml` error: `std::net::Ipv4Addr` may not be held across an await point per `clippy.toml`
--> tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs:10:9 --> tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs:10:9
| |
LL | let x = Ipv4Addr::new(127, 0, 0, 1); LL | let x = Ipv4Addr::new(127, 0, 0, 1);
| ^ | ^
error: `std::string::String` may not be held across an `await` point per `clippy.toml` error: `std::string::String` may not be held across an await point per `clippy.toml`
--> tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs:33:13 --> tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs:33:13
| |
LL | let _x = String::from("hi!"); LL | let _x = String::from("hi!");

View File

@ -8,7 +8,7 @@ mod std_mutex {
pub async fn bad(x: &Mutex<u32>) -> u32 { pub async fn bad(x: &Mutex<u32>) -> u32 {
let guard = x.lock().unwrap(); let guard = x.lock().unwrap();
//~^ ERROR: this `MutexGuard` is held across an `await` point //~^ ERROR: this `MutexGuard` is held across an await point
baz().await baz().await
} }
@ -24,13 +24,13 @@ pub async fn good(x: &Mutex<u32>) -> u32 {
pub async fn bad_rw(x: &RwLock<u32>) -> u32 { pub async fn bad_rw(x: &RwLock<u32>) -> u32 {
let guard = x.read().unwrap(); let guard = x.read().unwrap();
//~^ ERROR: this `MutexGuard` is held across an `await` point //~^ ERROR: this `MutexGuard` is held across an await point
baz().await baz().await
} }
pub async fn bad_rw_write(x: &RwLock<u32>) -> u32 { pub async fn bad_rw_write(x: &RwLock<u32>) -> u32 {
let mut guard = x.write().unwrap(); let mut guard = x.write().unwrap();
//~^ ERROR: this `MutexGuard` is held across an `await` point //~^ ERROR: this `MutexGuard` is held across an await point
baz().await baz().await
} }
@ -52,7 +52,7 @@ pub async fn also_bad(x: &Mutex<u32>) -> u32 {
let first = baz().await; let first = baz().await;
let guard = x.lock().unwrap(); let guard = x.lock().unwrap();
//~^ ERROR: this `MutexGuard` is held across an `await` point //~^ ERROR: this `MutexGuard` is held across an await point
let second = baz().await; let second = baz().await;
@ -66,7 +66,7 @@ pub async fn not_good(x: &Mutex<u32>) -> u32 {
let second = { let second = {
let guard = x.lock().unwrap(); let guard = x.lock().unwrap();
//~^ ERROR: this `MutexGuard` is held across an `await` point //~^ ERROR: this `MutexGuard` is held across an await point
baz().await baz().await
}; };
@ -79,7 +79,7 @@ pub async fn not_good(x: &Mutex<u32>) -> u32 {
pub fn block_bad(x: &Mutex<u32>) -> impl std::future::Future<Output = u32> + '_ { pub fn block_bad(x: &Mutex<u32>) -> impl std::future::Future<Output = u32> + '_ {
async move { async move {
let guard = x.lock().unwrap(); let guard = x.lock().unwrap();
//~^ ERROR: this `MutexGuard` is held across an `await` point //~^ ERROR: this `MutexGuard` is held across an await point
baz().await baz().await
} }
} }
@ -92,7 +92,7 @@ mod parking_lot_mutex {
pub async fn bad(x: &Mutex<u32>) -> u32 { pub async fn bad(x: &Mutex<u32>) -> u32 {
let guard = x.lock(); let guard = x.lock();
//~^ ERROR: this `MutexGuard` is held across an `await` point //~^ ERROR: this `MutexGuard` is held across an await point
baz().await baz().await
} }
@ -108,13 +108,13 @@ pub async fn good(x: &Mutex<u32>) -> u32 {
pub async fn bad_rw(x: &RwLock<u32>) -> u32 { pub async fn bad_rw(x: &RwLock<u32>) -> u32 {
let guard = x.read(); let guard = x.read();
//~^ ERROR: this `MutexGuard` is held across an `await` point //~^ ERROR: this `MutexGuard` is held across an await point
baz().await baz().await
} }
pub async fn bad_rw_write(x: &RwLock<u32>) -> u32 { pub async fn bad_rw_write(x: &RwLock<u32>) -> u32 {
let mut guard = x.write(); let mut guard = x.write();
//~^ ERROR: this `MutexGuard` is held across an `await` point //~^ ERROR: this `MutexGuard` is held across an await point
baz().await baz().await
} }
@ -136,7 +136,7 @@ pub async fn also_bad(x: &Mutex<u32>) -> u32 {
let first = baz().await; let first = baz().await;
let guard = x.lock(); let guard = x.lock();
//~^ ERROR: this `MutexGuard` is held across an `await` point //~^ ERROR: this `MutexGuard` is held across an await point
let second = baz().await; let second = baz().await;
@ -150,7 +150,7 @@ pub async fn not_good(x: &Mutex<u32>) -> u32 {
let second = { let second = {
let guard = x.lock(); let guard = x.lock();
//~^ ERROR: this `MutexGuard` is held across an `await` point //~^ ERROR: this `MutexGuard` is held across an await point
baz().await baz().await
}; };
@ -163,7 +163,7 @@ pub async fn not_good(x: &Mutex<u32>) -> u32 {
pub fn block_bad(x: &Mutex<u32>) -> impl std::future::Future<Output = u32> + '_ { pub fn block_bad(x: &Mutex<u32>) -> impl std::future::Future<Output = u32> + '_ {
async move { async move {
let guard = x.lock(); let guard = x.lock();
//~^ ERROR: this `MutexGuard` is held across an `await` point //~^ ERROR: this `MutexGuard` is held across an await point
baz().await baz().await
} }
} }
@ -184,7 +184,7 @@ async fn no_await(x: std::sync::Mutex<u32>) {
// `*guard += 1` is removed it is picked up. // `*guard += 1` is removed it is picked up.
async fn dropped_before_await(x: std::sync::Mutex<u32>) { async fn dropped_before_await(x: std::sync::Mutex<u32>) {
let mut guard = x.lock().unwrap(); let mut guard = x.lock().unwrap();
//~^ ERROR: this `MutexGuard` is held across an `await` point //~^ ERROR: this `MutexGuard` is held across an await point
*guard += 1; *guard += 1;
drop(guard); drop(guard);
baz().await; baz().await;

View File

@ -1,11 +1,11 @@
error: this `MutexGuard` is held across an `await` point error: this `MutexGuard` is held across an await point
--> tests/ui/await_holding_lock.rs:10:13 --> tests/ui/await_holding_lock.rs:10:13
| |
LL | let guard = x.lock().unwrap(); LL | let guard = x.lock().unwrap();
| ^^^^^ | ^^^^^
| |
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`
note: these are all the `await` points this lock is held through note: these are all the await points this lock is held through
--> tests/ui/await_holding_lock.rs:12:15 --> tests/ui/await_holding_lock.rs:12:15
| |
LL | baz().await LL | baz().await
@ -13,40 +13,40 @@ LL | baz().await
= note: `-D clippy::await-holding-lock` implied by `-D warnings` = note: `-D clippy::await-holding-lock` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::await_holding_lock)]` = help: to override `-D warnings` add `#[allow(clippy::await_holding_lock)]`
error: this `MutexGuard` is held across an `await` point error: this `MutexGuard` is held across an await point
--> tests/ui/await_holding_lock.rs:26:13 --> tests/ui/await_holding_lock.rs:26:13
| |
LL | let guard = x.read().unwrap(); LL | let guard = x.read().unwrap();
| ^^^^^ | ^^^^^
| |
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`
note: these are all the `await` points this lock is held through note: these are all the await points this lock is held through
--> tests/ui/await_holding_lock.rs:28:15 --> tests/ui/await_holding_lock.rs:28:15
| |
LL | baz().await LL | baz().await
| ^^^^^ | ^^^^^
error: this `MutexGuard` is held across an `await` point error: this `MutexGuard` is held across an await point
--> tests/ui/await_holding_lock.rs:32:13 --> tests/ui/await_holding_lock.rs:32:13
| |
LL | let mut guard = x.write().unwrap(); LL | let mut guard = x.write().unwrap();
| ^^^^^^^^^ | ^^^^^^^^^
| |
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`
note: these are all the `await` points this lock is held through note: these are all the await points this lock is held through
--> tests/ui/await_holding_lock.rs:34:15 --> tests/ui/await_holding_lock.rs:34:15
| |
LL | baz().await LL | baz().await
| ^^^^^ | ^^^^^
error: this `MutexGuard` is held across an `await` point error: this `MutexGuard` is held across an await point
--> tests/ui/await_holding_lock.rs:54:13 --> tests/ui/await_holding_lock.rs:54:13
| |
LL | let guard = x.lock().unwrap(); LL | let guard = x.lock().unwrap();
| ^^^^^ | ^^^^^
| |
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`
note: these are all the `await` points this lock is held through note: these are all the await points this lock is held through
--> tests/ui/await_holding_lock.rs:57:28 --> tests/ui/await_holding_lock.rs:57:28
| |
LL | let second = baz().await; LL | let second = baz().await;
@ -55,79 +55,79 @@ LL |
LL | let third = baz().await; LL | let third = baz().await;
| ^^^^^ | ^^^^^
error: this `MutexGuard` is held across an `await` point error: this `MutexGuard` is held across an await point
--> tests/ui/await_holding_lock.rs:68:17 --> tests/ui/await_holding_lock.rs:68:17
| |
LL | let guard = x.lock().unwrap(); LL | let guard = x.lock().unwrap();
| ^^^^^ | ^^^^^
| |
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`
note: these are all the `await` points this lock is held through note: these are all the await points this lock is held through
--> tests/ui/await_holding_lock.rs:70:19 --> tests/ui/await_holding_lock.rs:70:19
| |
LL | baz().await LL | baz().await
| ^^^^^ | ^^^^^
error: this `MutexGuard` is held across an `await` point error: this `MutexGuard` is held across an await point
--> tests/ui/await_holding_lock.rs:81:17 --> tests/ui/await_holding_lock.rs:81:17
| |
LL | let guard = x.lock().unwrap(); LL | let guard = x.lock().unwrap();
| ^^^^^ | ^^^^^
| |
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`
note: these are all the `await` points this lock is held through note: these are all the await points this lock is held through
--> tests/ui/await_holding_lock.rs:83:19 --> tests/ui/await_holding_lock.rs:83:19
| |
LL | baz().await LL | baz().await
| ^^^^^ | ^^^^^
error: this `MutexGuard` is held across an `await` point error: this `MutexGuard` is held across an await point
--> tests/ui/await_holding_lock.rs:94:13 --> tests/ui/await_holding_lock.rs:94:13
| |
LL | let guard = x.lock(); LL | let guard = x.lock();
| ^^^^^ | ^^^^^
| |
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`
note: these are all the `await` points this lock is held through note: these are all the await points this lock is held through
--> tests/ui/await_holding_lock.rs:96:15 --> tests/ui/await_holding_lock.rs:96:15
| |
LL | baz().await LL | baz().await
| ^^^^^ | ^^^^^
error: this `MutexGuard` is held across an `await` point error: this `MutexGuard` is held across an await point
--> tests/ui/await_holding_lock.rs:110:13 --> tests/ui/await_holding_lock.rs:110:13
| |
LL | let guard = x.read(); LL | let guard = x.read();
| ^^^^^ | ^^^^^
| |
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`
note: these are all the `await` points this lock is held through note: these are all the await points this lock is held through
--> tests/ui/await_holding_lock.rs:112:15 --> tests/ui/await_holding_lock.rs:112:15
| |
LL | baz().await LL | baz().await
| ^^^^^ | ^^^^^
error: this `MutexGuard` is held across an `await` point error: this `MutexGuard` is held across an await point
--> tests/ui/await_holding_lock.rs:116:13 --> tests/ui/await_holding_lock.rs:116:13
| |
LL | let mut guard = x.write(); LL | let mut guard = x.write();
| ^^^^^^^^^ | ^^^^^^^^^
| |
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`
note: these are all the `await` points this lock is held through note: these are all the await points this lock is held through
--> tests/ui/await_holding_lock.rs:118:15 --> tests/ui/await_holding_lock.rs:118:15
| |
LL | baz().await LL | baz().await
| ^^^^^ | ^^^^^
error: this `MutexGuard` is held across an `await` point error: this `MutexGuard` is held across an await point
--> tests/ui/await_holding_lock.rs:138:13 --> tests/ui/await_holding_lock.rs:138:13
| |
LL | let guard = x.lock(); LL | let guard = x.lock();
| ^^^^^ | ^^^^^
| |
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`
note: these are all the `await` points this lock is held through note: these are all the await points this lock is held through
--> tests/ui/await_holding_lock.rs:141:28 --> tests/ui/await_holding_lock.rs:141:28
| |
LL | let second = baz().await; LL | let second = baz().await;
@ -136,40 +136,40 @@ LL |
LL | let third = baz().await; LL | let third = baz().await;
| ^^^^^ | ^^^^^
error: this `MutexGuard` is held across an `await` point error: this `MutexGuard` is held across an await point
--> tests/ui/await_holding_lock.rs:152:17 --> tests/ui/await_holding_lock.rs:152:17
| |
LL | let guard = x.lock(); LL | let guard = x.lock();
| ^^^^^ | ^^^^^
| |
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`
note: these are all the `await` points this lock is held through note: these are all the await points this lock is held through
--> tests/ui/await_holding_lock.rs:154:19 --> tests/ui/await_holding_lock.rs:154:19
| |
LL | baz().await LL | baz().await
| ^^^^^ | ^^^^^
error: this `MutexGuard` is held across an `await` point error: this `MutexGuard` is held across an await point
--> tests/ui/await_holding_lock.rs:165:17 --> tests/ui/await_holding_lock.rs:165:17
| |
LL | let guard = x.lock(); LL | let guard = x.lock();
| ^^^^^ | ^^^^^
| |
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`
note: these are all the `await` points this lock is held through note: these are all the await points this lock is held through
--> tests/ui/await_holding_lock.rs:167:19 --> tests/ui/await_holding_lock.rs:167:19
| |
LL | baz().await LL | baz().await
| ^^^^^ | ^^^^^
error: this `MutexGuard` is held across an `await` point error: this `MutexGuard` is held across an await point
--> tests/ui/await_holding_lock.rs:186:9 --> tests/ui/await_holding_lock.rs:186:9
| |
LL | let mut guard = x.lock().unwrap(); LL | let mut guard = x.lock().unwrap();
| ^^^^^^^^^ | ^^^^^^^^^
| |
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`
note: these are all the `await` points this lock is held through note: these are all the await points this lock is held through
--> tests/ui/await_holding_lock.rs:190:11 --> tests/ui/await_holding_lock.rs:190:11
| |
LL | baz().await; LL | baz().await;

View File

@ -4,13 +4,13 @@
async fn bad(x: &RefCell<u32>) -> u32 { async fn bad(x: &RefCell<u32>) -> u32 {
let b = x.borrow(); let b = x.borrow();
//~^ ERROR: this `RefCell` reference is held across an `await` point //~^ ERROR: this `RefCell` reference is held across an await point
baz().await baz().await
} }
async fn bad_mut(x: &RefCell<u32>) -> u32 { async fn bad_mut(x: &RefCell<u32>) -> u32 {
let b = x.borrow_mut(); let b = x.borrow_mut();
//~^ ERROR: this `RefCell` reference is held across an `await` point //~^ ERROR: this `RefCell` reference is held across an await point
baz().await baz().await
} }
@ -32,7 +32,7 @@ async fn also_bad(x: &RefCell<u32>) -> u32 {
let first = baz().await; let first = baz().await;
let b = x.borrow_mut(); let b = x.borrow_mut();
//~^ ERROR: this `RefCell` reference is held across an `await` point //~^ ERROR: this `RefCell` reference is held across an await point
let second = baz().await; let second = baz().await;
@ -45,7 +45,7 @@ async fn less_bad(x: &RefCell<u32>) -> u32 {
let first = baz().await; let first = baz().await;
let b = x.borrow_mut(); let b = x.borrow_mut();
//~^ ERROR: this `RefCell` reference is held across an `await` point //~^ ERROR: this `RefCell` reference is held across an await point
let second = baz().await; let second = baz().await;
@ -61,7 +61,7 @@ async fn not_good(x: &RefCell<u32>) -> u32 {
let second = { let second = {
let b = x.borrow_mut(); let b = x.borrow_mut();
//~^ ERROR: this `RefCell` reference is held across an `await` point //~^ ERROR: this `RefCell` reference is held across an await point
baz().await baz().await
}; };
@ -74,7 +74,7 @@ async fn not_good(x: &RefCell<u32>) -> u32 {
fn block_bad(x: &RefCell<u32>) -> impl std::future::Future<Output = u32> + '_ { fn block_bad(x: &RefCell<u32>) -> impl std::future::Future<Output = u32> + '_ {
async move { async move {
let b = x.borrow_mut(); let b = x.borrow_mut();
//~^ ERROR: this `RefCell` reference is held across an `await` point //~^ ERROR: this `RefCell` reference is held across an await point
baz().await baz().await
} }
} }

View File

@ -1,11 +1,11 @@
error: this `RefCell` reference is held across an `await` point error: this `RefCell` reference is held across an await point
--> tests/ui/await_holding_refcell_ref.rs:6:9 --> tests/ui/await_holding_refcell_ref.rs:6:9
| |
LL | let b = x.borrow(); LL | let b = x.borrow();
| ^ | ^
| |
= help: ensure the reference is dropped before calling `await` = help: ensure the reference is dropped before calling `await`
note: these are all the `await` points this reference is held through note: these are all the await points this reference is held through
--> tests/ui/await_holding_refcell_ref.rs:8:11 --> tests/ui/await_holding_refcell_ref.rs:8:11
| |
LL | baz().await LL | baz().await
@ -13,27 +13,27 @@ LL | baz().await
= note: `-D clippy::await-holding-refcell-ref` implied by `-D warnings` = note: `-D clippy::await-holding-refcell-ref` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::await_holding_refcell_ref)]` = help: to override `-D warnings` add `#[allow(clippy::await_holding_refcell_ref)]`
error: this `RefCell` reference is held across an `await` point error: this `RefCell` reference is held across an await point
--> tests/ui/await_holding_refcell_ref.rs:12:9 --> tests/ui/await_holding_refcell_ref.rs:12:9
| |
LL | let b = x.borrow_mut(); LL | let b = x.borrow_mut();
| ^ | ^
| |
= help: ensure the reference is dropped before calling `await` = help: ensure the reference is dropped before calling `await`
note: these are all the `await` points this reference is held through note: these are all the await points this reference is held through
--> tests/ui/await_holding_refcell_ref.rs:14:11 --> tests/ui/await_holding_refcell_ref.rs:14:11
| |
LL | baz().await LL | baz().await
| ^^^^^ | ^^^^^
error: this `RefCell` reference is held across an `await` point error: this `RefCell` reference is held across an await point
--> tests/ui/await_holding_refcell_ref.rs:34:9 --> tests/ui/await_holding_refcell_ref.rs:34:9
| |
LL | let b = x.borrow_mut(); LL | let b = x.borrow_mut();
| ^ | ^
| |
= help: ensure the reference is dropped before calling `await` = help: ensure the reference is dropped before calling `await`
note: these are all the `await` points this reference is held through note: these are all the await points this reference is held through
--> tests/ui/await_holding_refcell_ref.rs:37:24 --> tests/ui/await_holding_refcell_ref.rs:37:24
| |
LL | let second = baz().await; LL | let second = baz().await;
@ -42,40 +42,40 @@ LL |
LL | let third = baz().await; LL | let third = baz().await;
| ^^^^^ | ^^^^^
error: this `RefCell` reference is held across an `await` point error: this `RefCell` reference is held across an await point
--> tests/ui/await_holding_refcell_ref.rs:47:9 --> tests/ui/await_holding_refcell_ref.rs:47:9
| |
LL | let b = x.borrow_mut(); LL | let b = x.borrow_mut();
| ^ | ^
| |
= help: ensure the reference is dropped before calling `await` = help: ensure the reference is dropped before calling `await`
note: these are all the `await` points this reference is held through note: these are all the await points this reference is held through
--> tests/ui/await_holding_refcell_ref.rs:50:24 --> tests/ui/await_holding_refcell_ref.rs:50:24
| |
LL | let second = baz().await; LL | let second = baz().await;
| ^^^^^ | ^^^^^
error: this `RefCell` reference is held across an `await` point error: this `RefCell` reference is held across an await point
--> tests/ui/await_holding_refcell_ref.rs:63:13 --> tests/ui/await_holding_refcell_ref.rs:63:13
| |
LL | let b = x.borrow_mut(); LL | let b = x.borrow_mut();
| ^ | ^
| |
= help: ensure the reference is dropped before calling `await` = help: ensure the reference is dropped before calling `await`
note: these are all the `await` points this reference is held through note: these are all the await points this reference is held through
--> tests/ui/await_holding_refcell_ref.rs:65:15 --> tests/ui/await_holding_refcell_ref.rs:65:15
| |
LL | baz().await LL | baz().await
| ^^^^^ | ^^^^^
error: this `RefCell` reference is held across an `await` point error: this `RefCell` reference is held across an await point
--> tests/ui/await_holding_refcell_ref.rs:76:13 --> tests/ui/await_holding_refcell_ref.rs:76:13
| |
LL | let b = x.borrow_mut(); LL | let b = x.borrow_mut();
| ^ | ^
| |
= help: ensure the reference is dropped before calling `await` = help: ensure the reference is dropped before calling `await`
note: these are all the `await` points this reference is held through note: these are all the await points this reference is held through
--> tests/ui/await_holding_refcell_ref.rs:78:15 --> tests/ui/await_holding_refcell_ref.rs:78:15
| |
LL | baz().await LL | baz().await