From 74ea16301e2e6fb96ac8414761cf227775e64dfd Mon Sep 17 00:00:00 2001 From: Gus Wynn Date: Sat, 11 Sep 2021 12:06:05 -0700 Subject: [PATCH] skip the uninhabitated check and comments --- compiler/rustc_lint_defs/src/builtin.rs | 23 ++++++++++++++++++- compiler/rustc_passes/src/check_attr.rs | 8 +++---- .../src/check/generator_interior.rs | 18 +++++---------- src/test/ui/lint/must_not_suspend/boxed.rs | 2 +- .../feature-gate-must_not_suspend.rs | 2 +- .../ui/lint/must_not_suspend/other_items.rs | 8 +++++++ .../lint/must_not_suspend/other_items.stderr | 10 ++++++++ src/test/ui/lint/must_not_suspend/return.rs | 2 +- .../ui/lint/must_not_suspend/return.stderr | 4 ++-- src/test/ui/lint/must_not_suspend/trait.rs | 4 ++-- src/test/ui/lint/must_not_suspend/unit.rs | 2 +- src/test/ui/lint/must_not_suspend/warn.rs | 2 +- 12 files changed, 59 insertions(+), 26 deletions(-) create mode 100644 src/test/ui/lint/must_not_suspend/other_items.rs create mode 100644 src/test/ui/lint/must_not_suspend/other_items.stderr diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 386435034b6..0463cb2b765 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -315,7 +315,28 @@ 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, Warn, "Use of a `#[must_not_suspend]` value across a yield point", diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a31f3fe281e..3e59fc4f551 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1018,15 +1018,15 @@ impl CheckAttrVisitor<'tcx> { /// 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 { match target { - Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => { + Target::Struct | Target::Enum | Target::Union | Target::Trait => true, + _ => { self.tcx .sess - .struct_span_err(attr.span, "`must_not_suspend` attribute should be applied to a struct, enum, `impl Trait`, or `dyn Trait`") - .span_label(*span, "is a function") + .struct_span_err(attr.span, "`must_not_suspend` attribute should be applied to a struct, enum, or trait") + .span_label(*span, "is not a struct, enum, or trait") .emit(); false } - _ => true, } } diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index 118c6e9a273..c4c09a55a6e 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -124,7 +124,6 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> { check_must_not_suspend_ty( self.fcx, - ty::ParamEnv::empty(), ty, hir_id, expr, @@ -454,7 +453,6 @@ impl<'a, 'tcx> Visitor<'tcx> for ArmPatCollector<'a> { // for creating must_use diagnostics pub fn check_must_not_suspend_ty<'tcx>( fcx: &FnCtxt<'_, 'tcx>, - param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>, hir_id: HirId, expr: Option<&'tcx Expr<'tcx>>, @@ -464,8 +462,10 @@ pub fn check_must_not_suspend_ty<'tcx>( descr_post: &str, plural_len: usize, ) -> bool { + debug!("FOUND TYPE: {:?}", ty); 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; } @@ -478,7 +478,6 @@ pub fn check_must_not_suspend_ty<'tcx>( let descr_pre = &format!("{}boxed ", descr_pre); check_must_not_suspend_ty( fcx, - param_env, boxed_ty, hir_id, expr, @@ -547,28 +546,24 @@ pub fn check_must_not_suspend_ty<'tcx>( } ty::Tuple(ref tys) => { let mut has_emitted = false; - /* - let spans = if let hir::ExprKind::Tup(comps) = &expr.kind { + let spans = if let Some(hir::ExprKind::Tup(comps)) = expr.map(|e| &e.kind) { debug_assert_eq!(comps.len(), tys.len()); comps.iter().map(|e| e.span).collect() } else { vec![] }; - */ - let spans = vec![]; for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() { let descr_post = &format!(" in tuple element {}", i); let span = *spans.get(i).unwrap_or(&source_span); if check_must_not_suspend_ty( - fcx, param_env, ty, hir_id, expr, span, yield_span, descr_pre, descr_post, - plural_len, + fcx, ty, hir_id, expr, span, yield_span, descr_pre, descr_post, plural_len, ) { has_emitted = true; } } 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 Some(0) | None => false, // 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,); check_must_not_suspend_ty( fcx, - param_env, ty, hir_id, expr, diff --git a/src/test/ui/lint/must_not_suspend/boxed.rs b/src/test/ui/lint/must_not_suspend/boxed.rs index d64d07e5e0d..1f823fc559d 100644 --- a/src/test/ui/lint/must_not_suspend/boxed.rs +++ b/src/test/ui/lint/must_not_suspend/boxed.rs @@ -17,7 +17,7 @@ fn bar() -> Box { async fn other() {} pub async fn uhoh() { - let _guard = bar(); //~ boxed `Umm` held across + let _guard = bar(); //~ ERROR boxed `Umm` held across other().await; } diff --git a/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs b/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs index aff8ff33b65..1554408c174 100644 --- a/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs +++ b/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs @@ -1,6 +1,6 @@ // 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 { _i: i64 } diff --git a/src/test/ui/lint/must_not_suspend/other_items.rs b/src/test/ui/lint/must_not_suspend/other_items.rs new file mode 100644 index 00000000000..5aa1abb14d3 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/other_items.rs @@ -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() {} diff --git a/src/test/ui/lint/must_not_suspend/other_items.stderr b/src/test/ui/lint/must_not_suspend/other_items.stderr new file mode 100644 index 00000000000..41c8896921b --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/other_items.stderr @@ -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 + diff --git a/src/test/ui/lint/must_not_suspend/return.rs b/src/test/ui/lint/must_not_suspend/return.rs index 5f80e789376..5b1fa5e2721 100644 --- a/src/test/ui/lint/must_not_suspend/return.rs +++ b/src/test/ui/lint/must_not_suspend/return.rs @@ -2,7 +2,7 @@ #![feature(must_not_suspend)] #![deny(must_not_suspend)] -#[must_not_suspend] //~ attribute should be +#[must_not_suspend] //~ ERROR attribute should be fn foo() -> i32 { 0 } diff --git a/src/test/ui/lint/must_not_suspend/return.stderr b/src/test/ui/lint/must_not_suspend/return.stderr index ff1798320cf..fdada85eb4d 100644 --- a/src/test/ui/lint/must_not_suspend/return.stderr +++ b/src/test/ui/lint/must_not_suspend/return.stderr @@ -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 | LL | #[must_not_suspend] @@ -6,7 +6,7 @@ LL | #[must_not_suspend] LL | / fn foo() -> i32 { LL | | 0 LL | | } - | |_- is a function + | |_- is not a struct, enum, or trait error: aborting due to previous error diff --git a/src/test/ui/lint/must_not_suspend/trait.rs b/src/test/ui/lint/must_not_suspend/trait.rs index 0438e072ce6..6c911cb4b0f 100644 --- a/src/test/ui/lint/must_not_suspend/trait.rs +++ b/src/test/ui/lint/must_not_suspend/trait.rs @@ -18,8 +18,8 @@ fn r#dyn() -> Box { async fn other() {} pub async fn uhoh() { - let _guard1 = r#impl(); //~ implementer of `Wow` held across - let _guard2 = r#dyn(); //~ boxed `Wow` trait object held across + let _guard1 = r#impl(); //~ ERROR implementer of `Wow` held across + let _guard2 = r#dyn(); //~ ERROR boxed `Wow` trait object held across other().await; } diff --git a/src/test/ui/lint/must_not_suspend/unit.rs b/src/test/ui/lint/must_not_suspend/unit.rs index 4e87b801114..d3a19f70432 100644 --- a/src/test/ui/lint/must_not_suspend/unit.rs +++ b/src/test/ui/lint/must_not_suspend/unit.rs @@ -17,7 +17,7 @@ fn bar() -> Umm { async fn other() {} pub async fn uhoh() { - let _guard = bar(); //~ `Umm` held across + let _guard = bar(); //~ ERROR `Umm` held across other().await; } diff --git a/src/test/ui/lint/must_not_suspend/warn.rs b/src/test/ui/lint/must_not_suspend/warn.rs index d0d72384807..50a696ba523 100644 --- a/src/test/ui/lint/must_not_suspend/warn.rs +++ b/src/test/ui/lint/must_not_suspend/warn.rs @@ -17,7 +17,7 @@ fn bar() -> Umm { async fn other() {} pub async fn uhoh() { - let _guard = bar(); //~ `Umm` held across + let _guard = bar(); //~ WARNING `Umm` held across other().await; }