mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
skip the uninhabitated check and comments
This commit is contained in:
parent
67ee91e77e
commit
74ea16301e
@ -315,7 +315,28 @@ declare_lint! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// [the reference]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute
|
/// 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)
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// #[must_not_suspend]
|
||||||
|
/// struct SyncThing {}
|
||||||
|
///
|
||||||
|
/// async fn yield() {}
|
||||||
|
///
|
||||||
|
/// pub async fn uhoh() {
|
||||||
|
/// let guard = SyncThing {};
|
||||||
|
/// yield().await;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub MUST_NOT_SUSPEND,
|
pub MUST_NOT_SUSPEND,
|
||||||
Warn,
|
Warn,
|
||||||
"Use of a `#[must_not_suspend]` value across a yield point",
|
"Use of a `#[must_not_suspend]` value across a yield point",
|
||||||
|
@ -1018,15 +1018,15 @@ impl CheckAttrVisitor<'tcx> {
|
|||||||
/// Checks if `#[must_not_suspend]` is applied to a function. Returns `true` if valid.
|
/// Checks if `#[must_not_suspend]` is applied to a function. Returns `true` if valid.
|
||||||
fn check_must_not_suspend(&self, attr: &Attribute, span: &Span, target: Target) -> bool {
|
fn check_must_not_suspend(&self, attr: &Attribute, span: &Span, target: Target) -> bool {
|
||||||
match target {
|
match target {
|
||||||
Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => {
|
Target::Struct | Target::Enum | Target::Union | Target::Trait => true,
|
||||||
|
_ => {
|
||||||
self.tcx
|
self.tcx
|
||||||
.sess
|
.sess
|
||||||
.struct_span_err(attr.span, "`must_not_suspend` attribute should be applied to a struct, enum, `impl Trait`, or `dyn Trait`")
|
.struct_span_err(attr.span, "`must_not_suspend` attribute should be applied to a struct, enum, or trait")
|
||||||
.span_label(*span, "is a function")
|
.span_label(*span, "is not a struct, enum, or trait")
|
||||||
.emit();
|
.emit();
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
_ => true,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,6 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
|
|||||||
|
|
||||||
check_must_not_suspend_ty(
|
check_must_not_suspend_ty(
|
||||||
self.fcx,
|
self.fcx,
|
||||||
ty::ParamEnv::empty(),
|
|
||||||
ty,
|
ty,
|
||||||
hir_id,
|
hir_id,
|
||||||
expr,
|
expr,
|
||||||
@ -454,7 +453,6 @@ impl<'a, 'tcx> Visitor<'tcx> for ArmPatCollector<'a> {
|
|||||||
// for creating must_use diagnostics
|
// for creating must_use diagnostics
|
||||||
pub fn check_must_not_suspend_ty<'tcx>(
|
pub fn check_must_not_suspend_ty<'tcx>(
|
||||||
fcx: &FnCtxt<'_, 'tcx>,
|
fcx: &FnCtxt<'_, 'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
hir_id: HirId,
|
hir_id: HirId,
|
||||||
expr: Option<&'tcx Expr<'tcx>>,
|
expr: Option<&'tcx Expr<'tcx>>,
|
||||||
@ -464,8 +462,10 @@ pub fn check_must_not_suspend_ty<'tcx>(
|
|||||||
descr_post: &str,
|
descr_post: &str,
|
||||||
plural_len: usize,
|
plural_len: usize,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
debug!("FOUND TYPE: {:?}", ty);
|
||||||
if ty.is_unit()
|
if ty.is_unit()
|
||||||
|| fcx.tcx.is_ty_uninhabited_from(fcx.tcx.parent_module(hir_id).to_def_id(), ty, param_env)
|
// || 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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -478,7 +478,6 @@ pub fn check_must_not_suspend_ty<'tcx>(
|
|||||||
let descr_pre = &format!("{}boxed ", descr_pre);
|
let descr_pre = &format!("{}boxed ", descr_pre);
|
||||||
check_must_not_suspend_ty(
|
check_must_not_suspend_ty(
|
||||||
fcx,
|
fcx,
|
||||||
param_env,
|
|
||||||
boxed_ty,
|
boxed_ty,
|
||||||
hir_id,
|
hir_id,
|
||||||
expr,
|
expr,
|
||||||
@ -547,28 +546,24 @@ 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 hir::ExprKind::Tup(comps) = &expr.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 {
|
||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
let spans = vec![];
|
|
||||||
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(&source_span);
|
||||||
if check_must_not_suspend_ty(
|
if check_must_not_suspend_ty(
|
||||||
fcx, param_env, ty, hir_id, expr, span, yield_span, descr_pre, descr_post,
|
fcx, ty, hir_id, expr, span, yield_span, descr_pre, descr_post, plural_len,
|
||||||
plural_len,
|
|
||||||
) {
|
) {
|
||||||
has_emitted = true;
|
has_emitted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
has_emitted
|
has_emitted
|
||||||
}
|
}
|
||||||
ty::Array(ty, len) => match len.try_eval_usize(fcx.tcx, param_env) {
|
ty::Array(ty, len) => match len.try_eval_usize(fcx.tcx, fcx.param_env) {
|
||||||
// If the array is empty we don't lint, to avoid false positives
|
// If the array is empty we don't lint, to avoid false positives
|
||||||
Some(0) | None => false,
|
Some(0) | None => false,
|
||||||
// If the array is definitely non-empty, we can do `#[must_use]` checking.
|
// If the array is definitely non-empty, we can do `#[must_use]` checking.
|
||||||
@ -576,7 +571,6 @@ pub fn check_must_not_suspend_ty<'tcx>(
|
|||||||
let descr_pre = &format!("{}array{} of ", descr_pre, plural_suffix,);
|
let descr_pre = &format!("{}array{} of ", descr_pre, plural_suffix,);
|
||||||
check_must_not_suspend_ty(
|
check_must_not_suspend_ty(
|
||||||
fcx,
|
fcx,
|
||||||
param_env,
|
|
||||||
ty,
|
ty,
|
||||||
hir_id,
|
hir_id,
|
||||||
expr,
|
expr,
|
||||||
|
@ -17,7 +17,7 @@ fn bar() -> Box<Umm> {
|
|||||||
async fn other() {}
|
async fn other() {}
|
||||||
|
|
||||||
pub async fn uhoh() {
|
pub async fn uhoh() {
|
||||||
let _guard = bar(); //~ boxed `Umm` held across
|
let _guard = bar(); //~ ERROR boxed `Umm` held across
|
||||||
other().await;
|
other().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// edition:2018
|
// edition:2018
|
||||||
|
|
||||||
#[must_not_suspend = "You gotta use Umm's, ya know?"] //~ the `#[must_not_suspend]`
|
#[must_not_suspend = "You gotta use Umm's, ya know?"] //~ ERROR the `#[must_not_suspend]`
|
||||||
struct Umm {
|
struct Umm {
|
||||||
_i: i64
|
_i: i64
|
||||||
}
|
}
|
||||||
|
8
src/test/ui/lint/must_not_suspend/other_items.rs
Normal file
8
src/test/ui/lint/must_not_suspend/other_items.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// edition:2018
|
||||||
|
#![feature(must_not_suspend)]
|
||||||
|
#![deny(must_not_suspend)]
|
||||||
|
|
||||||
|
#[must_not_suspend] //~ ERROR attribute should be
|
||||||
|
mod inner {}
|
||||||
|
|
||||||
|
fn main() {}
|
10
src/test/ui/lint/must_not_suspend/other_items.stderr
Normal file
10
src/test/ui/lint/must_not_suspend/other_items.stderr
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
error: `must_not_suspend` attribute should be applied to a struct, enum, or trait
|
||||||
|
--> $DIR/other_items.rs:5:1
|
||||||
|
|
|
||||||
|
LL | #[must_not_suspend]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL | mod inner {}
|
||||||
|
| ------------ is not a struct, enum, or trait
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
@ -2,7 +2,7 @@
|
|||||||
#![feature(must_not_suspend)]
|
#![feature(must_not_suspend)]
|
||||||
#![deny(must_not_suspend)]
|
#![deny(must_not_suspend)]
|
||||||
|
|
||||||
#[must_not_suspend] //~ attribute should be
|
#[must_not_suspend] //~ ERROR attribute should be
|
||||||
fn foo() -> i32 {
|
fn foo() -> i32 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: `must_not_suspend` attribute should be applied to a struct, enum, `impl Trait`, or `dyn Trait`
|
error: `must_not_suspend` attribute should be applied to a struct, enum, or trait
|
||||||
--> $DIR/return.rs:5:1
|
--> $DIR/return.rs:5:1
|
||||||
|
|
|
|
||||||
LL | #[must_not_suspend]
|
LL | #[must_not_suspend]
|
||||||
@ -6,7 +6,7 @@ LL | #[must_not_suspend]
|
|||||||
LL | / fn foo() -> i32 {
|
LL | / fn foo() -> i32 {
|
||||||
LL | | 0
|
LL | | 0
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_- is a function
|
| |_- is not a struct, enum, or trait
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@ fn r#dyn() -> Box<dyn Wow> {
|
|||||||
async fn other() {}
|
async fn other() {}
|
||||||
|
|
||||||
pub async fn uhoh() {
|
pub async fn uhoh() {
|
||||||
let _guard1 = r#impl(); //~ implementer of `Wow` held across
|
let _guard1 = r#impl(); //~ ERROR implementer of `Wow` held across
|
||||||
let _guard2 = r#dyn(); //~ boxed `Wow` trait object held across
|
let _guard2 = r#dyn(); //~ ERROR boxed `Wow` trait object held across
|
||||||
|
|
||||||
other().await;
|
other().await;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ fn bar() -> Umm {
|
|||||||
async fn other() {}
|
async fn other() {}
|
||||||
|
|
||||||
pub async fn uhoh() {
|
pub async fn uhoh() {
|
||||||
let _guard = bar(); //~ `Umm` held across
|
let _guard = bar(); //~ ERROR `Umm` held across
|
||||||
other().await;
|
other().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ fn bar() -> Umm {
|
|||||||
async fn other() {}
|
async fn other() {}
|
||||||
|
|
||||||
pub async fn uhoh() {
|
pub async fn uhoh() {
|
||||||
let _guard = bar(); //~ `Umm` held across
|
let _guard = bar(); //~ WARNING `Umm` held across
|
||||||
other().await;
|
other().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user