/// Allows `let...else` statements.
(active, let_else, "1.56.0", Some(87335), None),
- /// Allows `#[must_not_suspend]`.
- (active, must_not_suspend, "1.56.0", Some(83310), None),
+ /// Allows the `#[must_not_suspend]` attribute.
+ (active, must_not_suspend, "1.57.0", Some(83310), None),
// -------------------------------------------------------------------------
}
declare_lint! {
- /// The `must_not_suspend` lint detects values that are marked with the `#[must_not_suspend]`
- /// attribute being held across yield points. A "yield" point is usually a `.await` in an async
- /// function.
- ///
- /// This attribute can be used to mark values that are semantically incorrect across yields
- /// (like certain types of timers), values that have async alternatives, and values that
- /// regularly cause problems with the `Send`-ness of async fn's returned futures (like
- /// `MutexGuard`'s)
+ /// The `must_not_suspend` lint guards against values that shouldn't be held across yield points
+ /// (`.await`)
///
/// ### Example
///
/// yield_now().await;
/// }
/// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// The `must_not_suspend` lint detects values that are marked with the `#[must_not_suspend]`
+ /// attribute being held across yield points. A "yield" point is usually a `.await` in an async
+ /// function.
+ ///
+ /// This attribute can be used to mark values that are semantically incorrect across yields
+ /// (like certain types of timers), values that have async alternatives, and values that
+ /// regularly cause problems with the `Send`-ness of async fn's returned futures (like
+ /// `MutexGuard`'s)
+ ///
pub MUST_NOT_SUSPEND,
Warn,
- "Use of a `#[must_not_suspend]` value across a yield point",
+ "use of a `#[must_not_suspend]` value across a yield point",
}
declare_lint! {
plural_len: usize,
) -> bool {
if ty.is_unit()
+ // FIXME: should this check `is_ty_uninhabited_from`. This query is not available in this stage
+ // of typeck (before ReVar and RePlaceholder are removed), but may remove noise, like in
+ // `must_use`
// || fcx.tcx.is_ty_uninhabited_from(fcx.tcx.parent_module(hir_id).to_def_id(), ty, fcx.param_env)
- // FIXME: should this check is_ty_uninhabited_from
{
return true;
}
descr_pre,
descr_post,
),
+ // FIXME: support adding the attribute to TAITs
ty::Opaque(def, _) => {
let mut has_emitted = false;
for &(predicate, _) in fcx.tcx.explicit_item_bounds(def) {
);
let mut err = lint.build(&msg);
+ // add span pointing to the offending yield/await
+ err.span_label(yield_span, "the value is held across this yield point");
+
// Add optional reason note
if let Some(note) = attr.value_str() {
- err.note(¬e.as_str());
+ err.span_note(source_span, ¬e.as_str());
}
- // add span pointing to the offending yield/await)
- err.span_label(yield_span, "The value is held across this yield point");
-
// Add some quick suggestions on what to do
err.span_help(
source_span,
- "`drop` this value before the yield point, or use a block (`{ ... }`) \"
+ "`drop` this value before the yield point, or use a block (`{ ... }`) \
to shrink its scope",
);
LL | let _guard = bar();
| ^^^^^^
LL | other().await;
- | ------------- The value is held across this yield point
+ | ------------- the value is held across this yield point
|
note: the lint level is defined here
--> $DIR/boxed.rs:3:9
|
LL | #![deny(must_not_suspend)]
| ^^^^^^^^^^^^^^^^
- = note: You gotta use Umm's, ya know?
-help: `drop` this value before the yield point, or use a block (`{ ... }`) "
- to shrink its scope
+note: You gotta use Umm's, ya know?
+ --> $DIR/boxed.rs:20:9
+ |
+LL | let _guard = bar();
+ | ^^^^^^
+help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
--> $DIR/boxed.rs:20:9
|
LL | let _guard = bar();
| ^^^^^^
...
LL | other().await;
- | ------------- The value is held across this yield point
+ | ------------- the value is held across this yield point
|
note: the lint level is defined here
--> $DIR/ref.rs:3:9
|
LL | #![deny(must_not_suspend)]
| ^^^^^^^^^^^^^^^^
- = note: You gotta use Umm's, ya know?
-help: `drop` this value before the yield point, or use a block (`{ ... }`) "
- to shrink its scope
+note: You gotta use Umm's, ya know?
+ --> $DIR/ref.rs:18:26
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^^
+help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
--> $DIR/ref.rs:18:26
|
LL | let guard = &mut self.u;
| ^^^^^^
...
LL | other().await;
- | ------------- The value is held across this yield point
+ | ------------- the value is held across this yield point
|
- = note: You gotta use Umm's, ya know?
-help: `drop` this value before the yield point, or use a block (`{ ... }`) "
- to shrink its scope
+note: You gotta use Umm's, ya know?
+ --> $DIR/ref.rs:18:26
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^^
+help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
--> $DIR/ref.rs:18:26
|
LL | let guard = &mut self.u;
| ^^^^^^^
...
LL | other().await;
- | ------------- The value is held across this yield point
+ | ------------- the value is held across this yield point
|
note: the lint level is defined here
--> $DIR/trait.rs:3:9
|
LL | #![deny(must_not_suspend)]
| ^^^^^^^^^^^^^^^^
-help: `drop` this value before the yield point, or use a block (`{ ... }`) "
- to shrink its scope
+help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
--> $DIR/trait.rs:21:9
|
LL | let _guard1 = r#impl();
| ^^^^^^^
LL |
LL | other().await;
- | ------------- The value is held across this yield point
+ | ------------- the value is held across this yield point
|
-help: `drop` this value before the yield point, or use a block (`{ ... }`) "
- to shrink its scope
+help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
--> $DIR/trait.rs:22:9
|
LL | let _guard2 = r#dyn();
LL | let _guard = bar();
| ^^^^^^
LL | other().await;
- | ------------- The value is held across this yield point
+ | ------------- the value is held across this yield point
|
note: the lint level is defined here
--> $DIR/unit.rs:3:9
|
LL | #![deny(must_not_suspend)]
| ^^^^^^^^^^^^^^^^
- = note: You gotta use Umm's, ya know?
-help: `drop` this value before the yield point, or use a block (`{ ... }`) "
- to shrink its scope
+note: You gotta use Umm's, ya know?
+ --> $DIR/unit.rs:20:9
+ |
+LL | let _guard = bar();
+ | ^^^^^^
+help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
--> $DIR/unit.rs:20:9
|
LL | let _guard = bar();
LL | let _guard = bar();
| ^^^^^^
LL | other().await;
- | ------------- The value is held across this yield point
+ | ------------- the value is held across this yield point
|
= note: `#[warn(must_not_suspend)]` on by default
- = note: You gotta use Umm's, ya know?
-help: `drop` this value before the yield point, or use a block (`{ ... }`) "
- to shrink its scope
+note: You gotta use Umm's, ya know?
+ --> $DIR/warn.rs:20:9
+ |
+LL | let _guard = bar();
+ | ^^^^^^
+help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
--> $DIR/warn.rs:20:9
|
LL | let _guard = bar();