factor into struct, and comments
This commit is contained in:
parent
2af1ebfbdf
commit
110aecd23e
8 changed files with 104 additions and 92 deletions
|
@ -315,7 +315,7 @@ declare_lint! {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// The `must_not_suspend` lint guards against values that shouldn't be held across yield points
|
/// The `must_not_suspend` lint guards against values that shouldn't be held across suspend points
|
||||||
/// (`.await`)
|
/// (`.await`)
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
|
@ -339,10 +339,10 @@ declare_lint! {
|
||||||
/// ### Explanation
|
/// ### Explanation
|
||||||
///
|
///
|
||||||
/// The `must_not_suspend` lint detects values that are marked with the `#[must_not_suspend]`
|
/// 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
|
/// attribute being held across suspend points. A "suspend" point is usually a `.await` in an async
|
||||||
/// function.
|
/// function.
|
||||||
///
|
///
|
||||||
/// This attribute can be used to mark values that are semantically incorrect across yields
|
/// This attribute can be used to mark values that are semantically incorrect across suspends
|
||||||
/// (like certain types of timers), values that have async alternatives, and values that
|
/// (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
|
/// regularly cause problems with the `Send`-ness of async fn's returned futures (like
|
||||||
/// `MutexGuard`'s)
|
/// `MutexGuard`'s)
|
||||||
|
|
|
@ -126,12 +126,13 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
|
||||||
self.fcx,
|
self.fcx,
|
||||||
ty,
|
ty,
|
||||||
hir_id,
|
hir_id,
|
||||||
expr,
|
SuspendCheckData {
|
||||||
source_span,
|
expr,
|
||||||
yield_data.span,
|
source_span,
|
||||||
"",
|
yield_span: yield_data.span,
|
||||||
"",
|
plural_len: 1,
|
||||||
1,
|
..Default::default()
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
self.types.insert(ty::GeneratorInteriorTypeCause {
|
self.types.insert(ty::GeneratorInteriorTypeCause {
|
||||||
|
@ -448,6 +449,16 @@ impl<'a, 'tcx> Visitor<'tcx> for ArmPatCollector<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct SuspendCheckData<'a, 'tcx> {
|
||||||
|
expr: Option<&'tcx Expr<'tcx>>,
|
||||||
|
source_span: Span,
|
||||||
|
yield_span: Span,
|
||||||
|
descr_pre: &'a str,
|
||||||
|
descr_post: &'a str,
|
||||||
|
plural_len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
// Returns whether it emitted a diagnostic or not
|
// Returns whether it emitted a diagnostic or not
|
||||||
// Note that this fn and the proceding one are based on the code
|
// Note that this fn and the proceding one are based on the code
|
||||||
// for creating must_use diagnostics
|
// for creating must_use diagnostics
|
||||||
|
@ -455,12 +466,7 @@ pub fn check_must_not_suspend_ty<'tcx>(
|
||||||
fcx: &FnCtxt<'_, 'tcx>,
|
fcx: &FnCtxt<'_, 'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
hir_id: HirId,
|
hir_id: HirId,
|
||||||
expr: Option<&'tcx Expr<'tcx>>,
|
data: SuspendCheckData<'_, 'tcx>,
|
||||||
source_span: Span,
|
|
||||||
yield_span: Span,
|
|
||||||
descr_pre: &str,
|
|
||||||
descr_post: &str,
|
|
||||||
plural_len: usize,
|
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if ty.is_unit()
|
if ty.is_unit()
|
||||||
// FIXME: should this check `is_ty_uninhabited_from`. This query is not available in this stage
|
// FIXME: should this check `is_ty_uninhabited_from`. This query is not available in this stage
|
||||||
|
@ -468,36 +474,18 @@ pub fn check_must_not_suspend_ty<'tcx>(
|
||||||
// `must_use`
|
// `must_use`
|
||||||
// || fcx.tcx.is_ty_uninhabited_from(fcx.tcx.parent_module(hir_id).to_def_id(), ty, fcx.param_env)
|
// || fcx.tcx.is_ty_uninhabited_from(fcx.tcx.parent_module(hir_id).to_def_id(), ty, fcx.param_env)
|
||||||
{
|
{
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let plural_suffix = pluralize!(plural_len);
|
let plural_suffix = pluralize!(data.plural_len);
|
||||||
|
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Adt(..) if ty.is_box() => {
|
ty::Adt(..) if ty.is_box() => {
|
||||||
let boxed_ty = ty.boxed_ty();
|
let boxed_ty = ty.boxed_ty();
|
||||||
let descr_pre = &format!("{}boxed ", descr_pre);
|
let descr_pre = &format!("{}boxed ", data.descr_pre);
|
||||||
check_must_not_suspend_ty(
|
check_must_not_suspend_ty(fcx, boxed_ty, hir_id, SuspendCheckData { descr_pre, ..data })
|
||||||
fcx,
|
|
||||||
boxed_ty,
|
|
||||||
hir_id,
|
|
||||||
expr,
|
|
||||||
source_span,
|
|
||||||
yield_span,
|
|
||||||
descr_pre,
|
|
||||||
descr_post,
|
|
||||||
plural_len,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
ty::Adt(def, _) => check_must_not_suspend_def(
|
ty::Adt(def, _) => check_must_not_suspend_def(fcx.tcx, def.did, hir_id, data),
|
||||||
fcx.tcx,
|
|
||||||
def.did,
|
|
||||||
hir_id,
|
|
||||||
source_span,
|
|
||||||
yield_span,
|
|
||||||
descr_pre,
|
|
||||||
descr_post,
|
|
||||||
),
|
|
||||||
// FIXME: support adding the attribute to TAITs
|
// FIXME: support adding the attribute to TAITs
|
||||||
ty::Opaque(def, _) => {
|
ty::Opaque(def, _) => {
|
||||||
let mut has_emitted = false;
|
let mut has_emitted = false;
|
||||||
|
@ -507,15 +495,12 @@ pub fn check_must_not_suspend_ty<'tcx>(
|
||||||
predicate.kind().skip_binder()
|
predicate.kind().skip_binder()
|
||||||
{
|
{
|
||||||
let def_id = poly_trait_predicate.trait_ref.def_id;
|
let def_id = poly_trait_predicate.trait_ref.def_id;
|
||||||
let descr_pre = &format!("{}implementer{} of ", descr_pre, plural_suffix,);
|
let descr_pre = &format!("{}implementer{} of ", data.descr_pre, plural_suffix);
|
||||||
if check_must_not_suspend_def(
|
if check_must_not_suspend_def(
|
||||||
fcx.tcx,
|
fcx.tcx,
|
||||||
def_id,
|
def_id,
|
||||||
hir_id,
|
hir_id,
|
||||||
source_span,
|
SuspendCheckData { descr_pre, ..data },
|
||||||
yield_span,
|
|
||||||
descr_pre,
|
|
||||||
descr_post,
|
|
||||||
) {
|
) {
|
||||||
has_emitted = true;
|
has_emitted = true;
|
||||||
break;
|
break;
|
||||||
|
@ -529,15 +514,12 @@ pub fn check_must_not_suspend_ty<'tcx>(
|
||||||
for predicate in binder.iter() {
|
for predicate in binder.iter() {
|
||||||
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
|
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
|
||||||
let def_id = trait_ref.def_id;
|
let def_id = trait_ref.def_id;
|
||||||
let descr_post = &format!(" trait object{}{}", plural_suffix, descr_post,);
|
let descr_post = &format!(" trait object{}{}", plural_suffix, data.descr_post);
|
||||||
if check_must_not_suspend_def(
|
if check_must_not_suspend_def(
|
||||||
fcx.tcx,
|
fcx.tcx,
|
||||||
def_id,
|
def_id,
|
||||||
hir_id,
|
hir_id,
|
||||||
source_span,
|
SuspendCheckData { descr_post, ..data },
|
||||||
yield_span,
|
|
||||||
descr_pre,
|
|
||||||
descr_post,
|
|
||||||
) {
|
) {
|
||||||
has_emitted = true;
|
has_emitted = true;
|
||||||
break;
|
break;
|
||||||
|
@ -548,7 +530,7 @@ pub fn check_must_not_suspend_ty<'tcx>(
|
||||||
}
|
}
|
||||||
ty::Tuple(ref tys) => {
|
ty::Tuple(ref tys) => {
|
||||||
let mut has_emitted = false;
|
let mut has_emitted = false;
|
||||||
let spans = if let Some(hir::ExprKind::Tup(comps)) = expr.map(|e| &e.kind) {
|
let spans = if let Some(hir::ExprKind::Tup(comps)) = data.expr.map(|e| &e.kind) {
|
||||||
debug_assert_eq!(comps.len(), tys.len());
|
debug_assert_eq!(comps.len(), tys.len());
|
||||||
comps.iter().map(|e| e.span).collect()
|
comps.iter().map(|e| e.span).collect()
|
||||||
} else {
|
} else {
|
||||||
|
@ -556,9 +538,12 @@ pub fn check_must_not_suspend_ty<'tcx>(
|
||||||
};
|
};
|
||||||
for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() {
|
for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() {
|
||||||
let descr_post = &format!(" in tuple element {}", i);
|
let descr_post = &format!(" in tuple element {}", i);
|
||||||
let span = *spans.get(i).unwrap_or(&source_span);
|
let span = *spans.get(i).unwrap_or(&data.source_span);
|
||||||
if check_must_not_suspend_ty(
|
if check_must_not_suspend_ty(
|
||||||
fcx, ty, hir_id, expr, span, yield_span, descr_pre, descr_post, plural_len,
|
fcx,
|
||||||
|
ty,
|
||||||
|
hir_id,
|
||||||
|
SuspendCheckData { descr_post, source_span: span, ..data },
|
||||||
) {
|
) {
|
||||||
has_emitted = true;
|
has_emitted = true;
|
||||||
}
|
}
|
||||||
|
@ -566,17 +551,17 @@ pub fn check_must_not_suspend_ty<'tcx>(
|
||||||
has_emitted
|
has_emitted
|
||||||
}
|
}
|
||||||
ty::Array(ty, len) => {
|
ty::Array(ty, len) => {
|
||||||
let descr_pre = &format!("{}array{} of ", descr_pre, plural_suffix,);
|
let descr_pre = &format!("{}array{} of ", data.descr_pre, plural_suffix);
|
||||||
check_must_not_suspend_ty(
|
check_must_not_suspend_ty(
|
||||||
fcx,
|
fcx,
|
||||||
ty,
|
ty,
|
||||||
hir_id,
|
hir_id,
|
||||||
expr,
|
SuspendCheckData {
|
||||||
source_span,
|
descr_pre,
|
||||||
yield_span,
|
plural_len: len.try_eval_usize(fcx.tcx, fcx.param_env).unwrap_or(0) as usize
|
||||||
descr_pre,
|
+ 1,
|
||||||
descr_post,
|
..data
|
||||||
len.try_eval_usize(fcx.tcx, fcx.param_env).unwrap_or(0) as usize + 1,
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -587,39 +572,38 @@ fn check_must_not_suspend_def(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
hir_id: HirId,
|
hir_id: HirId,
|
||||||
source_span: Span,
|
data: SuspendCheckData<'_, '_>,
|
||||||
yield_span: Span,
|
|
||||||
descr_pre_path: &str,
|
|
||||||
descr_post_path: &str,
|
|
||||||
) -> bool {
|
) -> bool {
|
||||||
for attr in tcx.get_attrs(def_id).iter() {
|
for attr in tcx.get_attrs(def_id).iter() {
|
||||||
if attr.has_name(sym::must_not_suspend) {
|
if attr.has_name(sym::must_not_suspend) {
|
||||||
tcx.struct_span_lint_hir(
|
tcx.struct_span_lint_hir(
|
||||||
rustc_session::lint::builtin::MUST_NOT_SUSPEND,
|
rustc_session::lint::builtin::MUST_NOT_SUSPEND,
|
||||||
hir_id,
|
hir_id,
|
||||||
source_span,
|
data.source_span,
|
||||||
|lint| {
|
|lint| {
|
||||||
let msg = format!(
|
let msg = format!(
|
||||||
"{}`{}`{} held across a yield point, but should not be",
|
"{}`{}`{} held across a suspend point, but should not be",
|
||||||
descr_pre_path,
|
data.descr_pre,
|
||||||
tcx.def_path_str(def_id),
|
tcx.def_path_str(def_id),
|
||||||
descr_post_path
|
data.descr_post,
|
||||||
);
|
);
|
||||||
let mut err = lint.build(&msg);
|
let mut err = lint.build(&msg);
|
||||||
|
|
||||||
// add span pointing to the offending yield/await
|
// add span pointing to the offending yield/await
|
||||||
err.span_label(yield_span, "the value is held across this yield point");
|
err.span_label(data.yield_span, "the value is held across this suspend point");
|
||||||
|
|
||||||
// Add optional reason note
|
// Add optional reason note
|
||||||
if let Some(note) = attr.value_str() {
|
if let Some(note) = attr.value_str() {
|
||||||
err.span_note(source_span, ¬e.as_str());
|
// FIXME(guswynn): consider formatting this better
|
||||||
|
err.span_note(data.source_span, ¬e.as_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add some quick suggestions on what to do
|
// Add some quick suggestions on what to do
|
||||||
|
// FIXME: can `drop` work as a suggestion here as well?
|
||||||
err.span_help(
|
err.span_help(
|
||||||
source_span,
|
data.source_span,
|
||||||
"`drop` this value before the yield point, or use a block (`{ ... }`) \
|
"consider using a block (`{ ... }`) \
|
||||||
to shrink its scope",
|
to shrink the value's scope, ending before the suspend point",
|
||||||
);
|
);
|
||||||
|
|
||||||
err.emit();
|
err.emit();
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
error: boxed `Umm` held across a yield point, but should not be
|
error: boxed `Umm` held across a suspend point, but should not be
|
||||||
--> $DIR/boxed.rs:20:9
|
--> $DIR/boxed.rs:20:9
|
||||||
|
|
|
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this yield point
|
| ------------- the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/boxed.rs:3:9
|
--> $DIR/boxed.rs:3:9
|
||||||
|
@ -16,7 +16,7 @@ note: You gotta use Umm's, ya know?
|
||||||
|
|
|
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
|
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
||||||
--> $DIR/boxed.rs:20:9
|
--> $DIR/boxed.rs:20:9
|
||||||
|
|
|
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
|
|
28
src/test/ui/lint/must_not_suspend/handled.rs
Normal file
28
src/test/ui/lint/must_not_suspend/handled.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// edition:2018
|
||||||
|
// run-pass
|
||||||
|
#![feature(must_not_suspend)]
|
||||||
|
#![deny(must_not_suspend)]
|
||||||
|
|
||||||
|
#[must_not_suspend = "You gotta use Umm's, ya know?"]
|
||||||
|
struct Umm {
|
||||||
|
_i: i64
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn bar() -> Umm {
|
||||||
|
Umm {
|
||||||
|
_i: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn other() {}
|
||||||
|
|
||||||
|
pub async fn uhoh() {
|
||||||
|
{
|
||||||
|
let _guard = bar();
|
||||||
|
}
|
||||||
|
other().await;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
error: `Umm` held across a yield point, but should not be
|
error: `Umm` held across a suspend point, but should not be
|
||||||
--> $DIR/ref.rs:18:26
|
--> $DIR/ref.rs:18:26
|
||||||
|
|
|
|
||||||
LL | let guard = &mut self.u;
|
LL | let guard = &mut self.u;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
...
|
...
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this yield point
|
| ------------- the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/ref.rs:3:9
|
--> $DIR/ref.rs:3:9
|
||||||
|
@ -17,27 +17,27 @@ note: You gotta use Umm's, ya know?
|
||||||
|
|
|
|
||||||
LL | let guard = &mut self.u;
|
LL | let guard = &mut self.u;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
|
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
||||||
--> $DIR/ref.rs:18:26
|
--> $DIR/ref.rs:18:26
|
||||||
|
|
|
|
||||||
LL | let guard = &mut self.u;
|
LL | let guard = &mut self.u;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: `Umm` held across a yield point, but should not be
|
error: `Umm` held across a suspend point, but should not be
|
||||||
--> $DIR/ref.rs:18:26
|
--> $DIR/ref.rs:18:26
|
||||||
|
|
|
|
||||||
LL | let guard = &mut self.u;
|
LL | let guard = &mut self.u;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
...
|
...
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this yield point
|
| ------------- the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: You gotta use Umm's, ya know?
|
note: You gotta use Umm's, ya know?
|
||||||
--> $DIR/ref.rs:18:26
|
--> $DIR/ref.rs:18:26
|
||||||
|
|
|
|
||||||
LL | let guard = &mut self.u;
|
LL | let guard = &mut self.u;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
|
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
||||||
--> $DIR/ref.rs:18:26
|
--> $DIR/ref.rs:18:26
|
||||||
|
|
|
|
||||||
LL | let guard = &mut self.u;
|
LL | let guard = &mut self.u;
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
error: implementer of `Wow` held across a yield point, but should not be
|
error: implementer of `Wow` held across a suspend point, but should not be
|
||||||
--> $DIR/trait.rs:21:9
|
--> $DIR/trait.rs:21:9
|
||||||
|
|
|
|
||||||
LL | let _guard1 = r#impl();
|
LL | let _guard1 = r#impl();
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
...
|
...
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this yield point
|
| ------------- the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/trait.rs:3:9
|
--> $DIR/trait.rs:3:9
|
||||||
|
|
|
|
||||||
LL | #![deny(must_not_suspend)]
|
LL | #![deny(must_not_suspend)]
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
|
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
||||||
--> $DIR/trait.rs:21:9
|
--> $DIR/trait.rs:21:9
|
||||||
|
|
|
|
||||||
LL | let _guard1 = r#impl();
|
LL | let _guard1 = r#impl();
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: boxed `Wow` trait object held across a yield point, but should not be
|
error: boxed `Wow` trait object held across a suspend point, but should not be
|
||||||
--> $DIR/trait.rs:22:9
|
--> $DIR/trait.rs:22:9
|
||||||
|
|
|
|
||||||
LL | let _guard2 = r#dyn();
|
LL | let _guard2 = r#dyn();
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
LL |
|
LL |
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this yield point
|
| ------------- the value is held across this suspend point
|
||||||
|
|
|
|
||||||
help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
|
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
||||||
--> $DIR/trait.rs:22:9
|
--> $DIR/trait.rs:22:9
|
||||||
|
|
|
|
||||||
LL | let _guard2 = r#dyn();
|
LL | let _guard2 = r#dyn();
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
error: `Umm` held across a yield point, but should not be
|
error: `Umm` held across a suspend point, but should not be
|
||||||
--> $DIR/unit.rs:20:9
|
--> $DIR/unit.rs:20:9
|
||||||
|
|
|
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this yield point
|
| ------------- the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/unit.rs:3:9
|
--> $DIR/unit.rs:3:9
|
||||||
|
@ -16,7 +16,7 @@ note: You gotta use Umm's, ya know?
|
||||||
|
|
|
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
|
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
||||||
--> $DIR/unit.rs:20:9
|
--> $DIR/unit.rs:20:9
|
||||||
|
|
|
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
warning: `Umm` held across a yield point, but should not be
|
warning: `Umm` held across a suspend point, but should not be
|
||||||
--> $DIR/warn.rs:20:9
|
--> $DIR/warn.rs:20:9
|
||||||
|
|
|
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this yield point
|
| ------------- the value is held across this suspend point
|
||||||
|
|
|
|
||||||
= note: `#[warn(must_not_suspend)]` on by default
|
= note: `#[warn(must_not_suspend)]` on by default
|
||||||
note: You gotta use Umm's, ya know?
|
note: You gotta use Umm's, ya know?
|
||||||
|
@ -12,7 +12,7 @@ note: You gotta use Umm's, ya know?
|
||||||
|
|
|
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
help: `drop` this value before the yield point, or use a block (`{ ... }`) to shrink its scope
|
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
||||||
--> $DIR/warn.rs:20:9
|
--> $DIR/warn.rs:20:9
|
||||||
|
|
|
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
|
|
Loading…
Reference in a new issue