From 50bb7a40e11918a93e19ca44ca8893e3b56a8ec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 16 Aug 2022 07:46:33 -0700 Subject: [PATCH 1/4] Tweak span for `#[must_use]` Do not point at whole statement, only at the expression (skip pointing at `;`) --- compiler/rustc_lint/src/unused.rs | 9 +++------ .../2229_closure_analysis/match/issue-87097.stderr | 4 ++-- .../cfg-attr-multi-true.stderr | 2 +- src/test/ui/generator/issue-52398.stderr | 4 ++-- src/test/ui/generator/issue-57084.stderr | 2 +- src/test/ui/generator/match-bindings.stderr | 2 +- src/test/ui/generator/reborrow-mut-upvar.stderr | 2 +- .../too-live-local-in-immovable-gen.stderr | 2 +- src/test/ui/generator/yield-in-args-rev.stderr | 2 +- src/test/ui/generator/yield-in-box.stderr | 2 +- src/test/ui/generator/yield-in-initializer.stderr | 2 +- src/test/ui/generator/yield-subtype.stderr | 2 +- src/test/ui/issues/issue-1460.stderr | 2 +- src/test/ui/issues/issue-16256.stderr | 2 +- src/test/ui/lint/fn_must_use.stderr | 12 ++++++------ .../ui/lint/unused/must-use-box-from-raw.stderr | 2 +- src/test/ui/lint/unused/must_use-array.stderr | 8 ++++---- .../lint/unused/must_use-in-stdlib-traits.stderr | 10 +++++----- src/test/ui/lint/unused/must_use-trait.stderr | 6 +++--- src/test/ui/lint/unused/must_use-unit.stderr | 4 ++-- src/test/ui/lint/unused/unused-closure.stderr | 14 +++++++------- src/test/ui/lint/unused/unused-result.stderr | 8 ++++---- .../lint/unused/unused_attributes-must_use.stderr | 14 +++++++------- src/test/ui/nll/issue-48623-generator.stderr | 2 +- 24 files changed, 58 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 46706e4984451..3e8bd7a374dea 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -87,17 +87,14 @@ declare_lint_pass!(UnusedResults => [UNUSED_MUST_USE, UNUSED_RESULTS]); impl<'tcx> LateLintPass<'tcx> for UnusedResults { fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) { - let expr = match s.kind { - hir::StmtKind::Semi(ref expr) => &**expr, - _ => return, - }; + let hir::StmtKind::Semi(expr) = s.kind else { return; }; if let hir::ExprKind::Ret(..) = expr.kind { return; } let ty = cx.typeck_results().expr_ty(&expr); - let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", 1); + let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, expr.span, "", "", 1); let mut fn_warned = false; let mut op_warned = false; @@ -119,7 +116,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { _ => None, }; if let Some(def_id) = maybe_def_id { - fn_warned = check_must_use_def(cx, def_id, s.span, "return value of ", ""); + fn_warned = check_must_use_def(cx, def_id, expr.span, "return value of ", ""); } else if type_permits_lack_of_use { // We don't warn about unused unit or uninhabited types. // (See https://github.com/rust-lang/rust/issues/43806 for details.) diff --git a/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr index 3840108597131..39ec71ba22a18 100644 --- a/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr +++ b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr @@ -16,7 +16,7 @@ LL | / || match out_ref { LL | | Variant::A => (), LL | | Variant::B => (), LL | | }; - | |______^ + | |_____^ | = note: closures are lazy and do nothing unless called = note: `#[warn(unused_must_use)]` on by default @@ -28,7 +28,7 @@ LL | / || match here.field { LL | | Variant::A => (), LL | | Variant::B => (), LL | | }; - | |______^ + | |_____^ | = note: closures are lazy and do nothing unless called diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr index 5f278f94b93bd..fbfcd45652f19 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr @@ -28,7 +28,7 @@ warning: unused `MustUseDeprecated` that must be used --> $DIR/cfg-attr-multi-true.rs:19:5 | LL | MustUseDeprecated::new(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/cfg-attr-multi-true.rs:7:9 diff --git a/src/test/ui/generator/issue-52398.stderr b/src/test/ui/generator/issue-52398.stderr index 30a6732f75956..539343275df60 100644 --- a/src/test/ui/generator/issue-52398.stderr +++ b/src/test/ui/generator/issue-52398.stderr @@ -4,7 +4,7 @@ warning: unused generator that must be used LL | / move || { LL | | A.test(yield); LL | | }; - | |______^ + | |_____^ | = note: generators are lazy and do nothing unless resumed = note: `#[warn(unused_must_use)]` on by default @@ -16,7 +16,7 @@ LL | / static move || { LL | | yield *y.borrow(); LL | | return "Done"; LL | | }; - | |______^ + | |_____^ | = note: generators are lazy and do nothing unless resumed diff --git a/src/test/ui/generator/issue-57084.stderr b/src/test/ui/generator/issue-57084.stderr index 29aca94408a82..8f1fc5e803194 100644 --- a/src/test/ui/generator/issue-57084.stderr +++ b/src/test/ui/generator/issue-57084.stderr @@ -7,7 +7,7 @@ LL | | loop { LL | | yield LL | | } LL | | }; - | |______^ + | |_____^ | = note: generators are lazy and do nothing unless resumed = note: `#[warn(unused_must_use)]` on by default diff --git a/src/test/ui/generator/match-bindings.stderr b/src/test/ui/generator/match-bindings.stderr index b911b6661909a..3dd2d595445aa 100644 --- a/src/test/ui/generator/match-bindings.stderr +++ b/src/test/ui/generator/match-bindings.stderr @@ -8,7 +8,7 @@ LL | | match Enum::A(String::new()) { ... | LL | | } LL | | }; - | |______^ + | |_____^ | = note: generators are lazy and do nothing unless resumed = note: `#[warn(unused_must_use)]` on by default diff --git a/src/test/ui/generator/reborrow-mut-upvar.stderr b/src/test/ui/generator/reborrow-mut-upvar.stderr index e83dbf833bfa7..2e1fec35eaf52 100644 --- a/src/test/ui/generator/reborrow-mut-upvar.stderr +++ b/src/test/ui/generator/reborrow-mut-upvar.stderr @@ -8,7 +8,7 @@ LL | | yield; ... | LL | | *bar = 2; LL | | }; - | |______^ + | |_____^ | = note: generators are lazy and do nothing unless resumed = note: `#[warn(unused_must_use)]` on by default diff --git a/src/test/ui/generator/too-live-local-in-immovable-gen.stderr b/src/test/ui/generator/too-live-local-in-immovable-gen.stderr index 5cb43067fee6b..e262f213f63d2 100644 --- a/src/test/ui/generator/too-live-local-in-immovable-gen.stderr +++ b/src/test/ui/generator/too-live-local-in-immovable-gen.stderr @@ -8,7 +8,7 @@ LL | | // and it should also find out that `a` is not live. ... | LL | | let _ = &a; LL | | }; - | |__________^ + | |_________^ | = note: generators are lazy and do nothing unless resumed = note: `#[warn(unused_must_use)]` on by default diff --git a/src/test/ui/generator/yield-in-args-rev.stderr b/src/test/ui/generator/yield-in-args-rev.stderr index c9e1ab722d47f..a87248f662100 100644 --- a/src/test/ui/generator/yield-in-args-rev.stderr +++ b/src/test/ui/generator/yield-in-args-rev.stderr @@ -5,7 +5,7 @@ LL | / || { LL | | let b = true; LL | | foo(yield, &b); LL | | }; - | |______^ + | |_____^ | = note: generators are lazy and do nothing unless resumed = note: `#[warn(unused_must_use)]` on by default diff --git a/src/test/ui/generator/yield-in-box.stderr b/src/test/ui/generator/yield-in-box.stderr index 8587e1dc663bc..9d03ee00800c8 100644 --- a/src/test/ui/generator/yield-in-box.stderr +++ b/src/test/ui/generator/yield-in-box.stderr @@ -8,7 +8,7 @@ LL | | let _t = box (&x, yield 0, &y); ... | LL | | } LL | | }; - | |______^ + | |_____^ | = note: generators are lazy and do nothing unless resumed = note: `#[warn(unused_must_use)]` on by default diff --git a/src/test/ui/generator/yield-in-initializer.stderr b/src/test/ui/generator/yield-in-initializer.stderr index 07de24662cf2e..ed14a2e3273af 100644 --- a/src/test/ui/generator/yield-in-initializer.stderr +++ b/src/test/ui/generator/yield-in-initializer.stderr @@ -8,7 +8,7 @@ LL | | // See https://github.com/rust-lang/rust/issues/52792 ... | LL | | } LL | | }; - | |______^ + | |_____^ | = note: generators are lazy and do nothing unless resumed = note: `#[warn(unused_must_use)]` on by default diff --git a/src/test/ui/generator/yield-subtype.stderr b/src/test/ui/generator/yield-subtype.stderr index fe10477bf7380..97862e91cd4a0 100644 --- a/src/test/ui/generator/yield-subtype.stderr +++ b/src/test/ui/generator/yield-subtype.stderr @@ -5,7 +5,7 @@ LL | / || { LL | | yield a; LL | | yield b; LL | | }; - | |______^ + | |_____^ | = note: generators are lazy and do nothing unless resumed = note: `#[warn(unused_must_use)]` on by default diff --git a/src/test/ui/issues/issue-1460.stderr b/src/test/ui/issues/issue-1460.stderr index f0ff2cafd4466..eb7661fad56db 100644 --- a/src/test/ui/issues/issue-1460.stderr +++ b/src/test/ui/issues/issue-1460.stderr @@ -2,7 +2,7 @@ warning: unused closure that must be used --> $DIR/issue-1460.rs:6:5 | LL | {|i: u32| if 1 == i { }}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: closures are lazy and do nothing unless called = note: `#[warn(unused_must_use)]` on by default diff --git a/src/test/ui/issues/issue-16256.stderr b/src/test/ui/issues/issue-16256.stderr index ca8e9a1bed337..d920530b57c69 100644 --- a/src/test/ui/issues/issue-16256.stderr +++ b/src/test/ui/issues/issue-16256.stderr @@ -2,7 +2,7 @@ warning: unused closure that must be used --> $DIR/issue-16256.rs:6:5 | LL | |c: u8| buf.push(c); - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ | = note: closures are lazy and do nothing unless called = note: `#[warn(unused_must_use)]` on by default diff --git a/src/test/ui/lint/fn_must_use.stderr b/src/test/ui/lint/fn_must_use.stderr index 2805720f035b8..657f23c60856f 100644 --- a/src/test/ui/lint/fn_must_use.stderr +++ b/src/test/ui/lint/fn_must_use.stderr @@ -2,7 +2,7 @@ warning: unused return value of `need_to_use_this_value` that must be used --> $DIR/fn_must_use.rs:55:5 | LL | need_to_use_this_value(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: it's important note: the lint level is defined here @@ -15,13 +15,13 @@ warning: unused return value of `MyStruct::need_to_use_this_method_value` that m --> $DIR/fn_must_use.rs:60:5 | LL | m.need_to_use_this_method_value(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused return value of `EvenNature::is_even` that must be used --> $DIR/fn_must_use.rs:61:5 | LL | m.is_even(); // trait method! - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^ | = note: no side effects @@ -29,19 +29,19 @@ warning: unused return value of `MyStruct::need_to_use_this_associated_function_ --> $DIR/fn_must_use.rs:64:5 | LL | MyStruct::need_to_use_this_associated_function_value(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused return value of `std::cmp::PartialEq::eq` that must be used --> $DIR/fn_must_use.rs:70:5 | LL | 2.eq(&3); - | ^^^^^^^^^ + | ^^^^^^^^ warning: unused return value of `std::cmp::PartialEq::eq` that must be used --> $DIR/fn_must_use.rs:71:5 | LL | m.eq(&n); - | ^^^^^^^^^ + | ^^^^^^^^ warning: unused comparison that must be used --> $DIR/fn_must_use.rs:74:5 diff --git a/src/test/ui/lint/unused/must-use-box-from-raw.stderr b/src/test/ui/lint/unused/must-use-box-from-raw.stderr index 011acc3bf5d6e..72118275774d1 100644 --- a/src/test/ui/lint/unused/must-use-box-from-raw.stderr +++ b/src/test/ui/lint/unused/must-use-box-from-raw.stderr @@ -2,7 +2,7 @@ warning: unused return value of `Box::::from_raw` that must be used --> $DIR/must-use-box-from-raw.rs:8:5 | LL | Box::from_raw(ptr); - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ | = note: call `drop(from_raw(ptr))` if you intend to drop the `Box` note: the lint level is defined here diff --git a/src/test/ui/lint/unused/must_use-array.stderr b/src/test/ui/lint/unused/must_use-array.stderr index 45a5317fccc6e..bba2b1ba078c6 100644 --- a/src/test/ui/lint/unused/must_use-array.stderr +++ b/src/test/ui/lint/unused/must_use-array.stderr @@ -2,7 +2,7 @@ error: unused array of `S` that must be used --> $DIR/must_use-array.rs:39:5 | LL | singleton(); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/must_use-array.rs:1:9 @@ -14,7 +14,7 @@ error: unused array of `S` that must be used --> $DIR/must_use-array.rs:40:5 | LL | many(); - | ^^^^^^^ + | ^^^^^^ error: unused array of `S` in tuple element 0 that must be used --> $DIR/must_use-array.rs:41:6 @@ -26,7 +26,7 @@ error: unused array of implementers of `T` that must be used --> $DIR/must_use-array.rs:42:5 | LL | array_of_impl_trait(); - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ error: unused array of boxed `T` trait objects in tuple element 1 that must be used --> $DIR/must_use-array.rs:43:5 @@ -38,7 +38,7 @@ error: unused array of arrays of arrays of `S` that must be used --> $DIR/must_use-array.rs:45:5 | LL | array_of_arrays_of_arrays(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr index f5199f43c74bd..ef738708d5f4e 100644 --- a/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr +++ b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr @@ -2,7 +2,7 @@ error: unused implementer of `Iterator` that must be used --> $DIR/must_use-in-stdlib-traits.rs:42:4 | LL | iterator(); - | ^^^^^^^^^^^ + | ^^^^^^^^^^ | = note: iterators are lazy and do nothing unless consumed note: the lint level is defined here @@ -15,7 +15,7 @@ error: unused implementer of `Future` that must be used --> $DIR/must_use-in-stdlib-traits.rs:43:4 | LL | future(); - | ^^^^^^^^^ + | ^^^^^^^^ | = note: futures do nothing unless you `.await` or poll them @@ -23,7 +23,7 @@ error: unused implementer of `FnOnce` that must be used --> $DIR/must_use-in-stdlib-traits.rs:44:4 | LL | square_fn_once(); - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ | = note: closures are lazy and do nothing unless called @@ -31,7 +31,7 @@ error: unused implementer of `FnMut` that must be used --> $DIR/must_use-in-stdlib-traits.rs:45:4 | LL | square_fn_mut(); - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | = note: closures are lazy and do nothing unless called @@ -39,7 +39,7 @@ error: unused implementer of `Fn` that must be used --> $DIR/must_use-in-stdlib-traits.rs:46:4 | LL | square_fn(); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^ | = note: closures are lazy and do nothing unless called diff --git a/src/test/ui/lint/unused/must_use-trait.stderr b/src/test/ui/lint/unused/must_use-trait.stderr index a42eb8841789d..2f54964848359 100644 --- a/src/test/ui/lint/unused/must_use-trait.stderr +++ b/src/test/ui/lint/unused/must_use-trait.stderr @@ -2,7 +2,7 @@ error: unused implementer of `Critical` that must be used --> $DIR/must_use-trait.rs:33:5 | LL | get_critical(); - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/must_use-trait.rs:1:9 @@ -14,13 +14,13 @@ error: unused boxed `Critical` trait object that must be used --> $DIR/must_use-trait.rs:34:5 | LL | get_boxed_critical(); - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ error: unused boxed boxed `Critical` trait object that must be used --> $DIR/must_use-trait.rs:35:5 | LL | get_nested_boxed_critical(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unused boxed `Critical` trait object in tuple element 1 that must be used --> $DIR/must_use-trait.rs:37:5 diff --git a/src/test/ui/lint/unused/must_use-unit.stderr b/src/test/ui/lint/unused/must_use-unit.stderr index 7f25a19350862..9fcbc5074ea80 100644 --- a/src/test/ui/lint/unused/must_use-unit.stderr +++ b/src/test/ui/lint/unused/must_use-unit.stderr @@ -2,7 +2,7 @@ error: unused return value of `foo` that must be used --> $DIR/must_use-unit.rs:13:5 | LL | foo(); - | ^^^^^^ + | ^^^^^ | note: the lint level is defined here --> $DIR/must_use-unit.rs:2:9 @@ -14,7 +14,7 @@ error: unused return value of `bar` that must be used --> $DIR/must_use-unit.rs:15:5 | LL | bar(); - | ^^^^^^ + | ^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/lint/unused/unused-closure.stderr b/src/test/ui/lint/unused/unused-closure.stderr index 4362abd2037ff..c3a82402e0a2e 100644 --- a/src/test/ui/lint/unused/unused-closure.stderr +++ b/src/test/ui/lint/unused/unused-closure.stderr @@ -4,7 +4,7 @@ error: unused closure that must be used LL | / || { LL | | println!("Hello!"); LL | | }; - | |______^ + | |_____^ | = note: closures are lazy and do nothing unless called note: the lint level is defined here @@ -17,7 +17,7 @@ error: unused implementer of `Future` that must be used --> $DIR/unused-closure.rs:13:5 | LL | async {}; - | ^^^^^^^^^ + | ^^^^^^^^ | = note: futures do nothing unless you `.await` or poll them @@ -25,7 +25,7 @@ error: unused closure that must be used --> $DIR/unused-closure.rs:14:5 | LL | || async {}; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^ | = note: closures are lazy and do nothing unless called @@ -33,7 +33,7 @@ error: unused closure that must be used --> $DIR/unused-closure.rs:15:5 | LL | async || {}; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^ | = note: closures are lazy and do nothing unless called @@ -41,7 +41,7 @@ error: unused array of boxed arrays of closures that must be used --> $DIR/unused-closure.rs:18:5 | LL | [Box::new([|| {}; 10]); 1]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: closures are lazy and do nothing unless called @@ -49,7 +49,7 @@ error: unused closure that must be used --> $DIR/unused-closure.rs:20:5 | LL | vec![|| "a"].pop().unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: closures are lazy and do nothing unless called @@ -57,7 +57,7 @@ error: unused closure that must be used --> $DIR/unused-closure.rs:23:9 | LL | || true; - | ^^^^^^^^ + | ^^^^^^^ | = note: closures are lazy and do nothing unless called diff --git a/src/test/ui/lint/unused/unused-result.stderr b/src/test/ui/lint/unused/unused-result.stderr index 087e06341cdde..4e1ba1fd9595f 100644 --- a/src/test/ui/lint/unused/unused-result.stderr +++ b/src/test/ui/lint/unused/unused-result.stderr @@ -2,7 +2,7 @@ error: unused `MustUse` that must be used --> $DIR/unused-result.rs:21:5 | LL | foo::(); - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/unused-result.rs:2:25 @@ -14,7 +14,7 @@ error: unused `MustUseMsg` that must be used --> $DIR/unused-result.rs:22:5 | LL | foo::(); - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ | = note: some message @@ -34,13 +34,13 @@ error: unused `MustUse` that must be used --> $DIR/unused-result.rs:35:5 | LL | foo::(); - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error: unused `MustUseMsg` that must be used --> $DIR/unused-result.rs:36:5 | LL | foo::(); - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ | = note: some message diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.stderr b/src/test/ui/lint/unused/unused_attributes-must_use.stderr index ce959ddbc4697..0f699429e0243 100644 --- a/src/test/ui/lint/unused/unused_attributes-must_use.stderr +++ b/src/test/ui/lint/unused/unused_attributes-must_use.stderr @@ -139,7 +139,7 @@ error: unused `X` that must be used --> $DIR/unused_attributes-must_use.rs:103:5 | LL | X; - | ^^ + | ^ | note: the lint level is defined here --> $DIR/unused_attributes-must_use.rs:2:28 @@ -151,37 +151,37 @@ error: unused `Y` that must be used --> $DIR/unused_attributes-must_use.rs:104:5 | LL | Y::Z; - | ^^^^^ + | ^^^^ error: unused `U` that must be used --> $DIR/unused_attributes-must_use.rs:105:5 | LL | U { unit: () }; - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ error: unused return value of `U::method` that must be used --> $DIR/unused_attributes-must_use.rs:106:5 | LL | U::method(); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^ error: unused return value of `foo` that must be used --> $DIR/unused_attributes-must_use.rs:107:5 | LL | foo(); - | ^^^^^^ + | ^^^^^ error: unused return value of `foreign_foo` that must be used --> $DIR/unused_attributes-must_use.rs:110:9 | LL | foreign_foo(); - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: unused return value of `Use::get_four` that must be used --> $DIR/unused_attributes-must_use.rs:118:5 | LL | ().get_four(); - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: aborting due to 28 previous errors diff --git a/src/test/ui/nll/issue-48623-generator.stderr b/src/test/ui/nll/issue-48623-generator.stderr index 1b35165db45dc..bfdfca2100406 100644 --- a/src/test/ui/nll/issue-48623-generator.stderr +++ b/src/test/ui/nll/issue-48623-generator.stderr @@ -2,7 +2,7 @@ warning: unused generator that must be used --> $DIR/issue-48623-generator.rs:15:5 | LL | move || { d; yield; &mut *r }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: generators are lazy and do nothing unless resumed = note: `#[warn(unused_must_use)]` on by default From 243496e1299bc6dddb3824a91f026da34f732199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 16 Aug 2022 07:56:42 -0700 Subject: [PATCH 2/4] Consider `#[must_use]` annotation on `async fn` as also affecting the `Future::Output` No longer lint against `#[must_use] async fn foo()`. When encountering a statement that awaits on a `Future`, check if the `Future`'s parent item is annotated with `#[must_use]` and emit a lint if so. This effectively makes `must_use` an annotation on the `Future::Output` instead of only the `Future` itself. Fix #78149. --- compiler/rustc_lint/src/unused.rs | 14 +++- compiler/rustc_passes/src/check_attr.rs | 14 +--- src/test/ui/lint/unused/unused-async.rs | 29 ++++++-- src/test/ui/lint/unused/unused-async.stderr | 79 ++++++++++++++------- 4 files changed, 93 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 3e8bd7a374dea..1a5515530ae9f 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -9,7 +9,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_infer::traits::util::elaborate_predicates_with_span; use rustc_middle::ty::adjustment; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, DefIdTree, Ty}; use rustc_span::symbol::Symbol; use rustc_span::symbol::{kw, sym}; use rustc_span::{BytePos, Span}; @@ -93,6 +93,18 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { return; } + if let hir::ExprKind::Match(await_expr, _arms, hir::MatchSource::AwaitDesugar) = expr.kind + && let ty = cx.typeck_results().expr_ty(&await_expr) + && let ty::Opaque(def_id, _) = ty.kind() + && cx.tcx.ty_is_opaque_future(ty) + && let parent = cx.tcx.parent(*def_id) + && check_must_use_def(cx, parent, expr.span, "awaited future returned by ", "") + { + // We have a bare `foo().await;` on an opaque type from an async function that was + // annotated with `#[must_use]`. + return; + } + let ty = cx.typeck_results().expr_ty(&expr); let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, expr.span, "", "", 1); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 27a57adf964a3..e0da0096c4e1e 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -139,7 +139,7 @@ impl CheckAttrVisitor<'_> { sym::collapse_debuginfo => self.check_collapse_debuginfo(attr, span, target), sym::const_trait => self.check_const_trait(attr, span, target), sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target), - sym::must_use => self.check_must_use(hir_id, &attr, span, target), + sym::must_use => self.check_must_use(hir_id, &attr, target), sym::rustc_pass_by_value => self.check_pass_by_value(&attr, span, target), sym::rustc_allow_incoherent_impl => { self.check_allow_incoherent_impl(&attr, span, target) @@ -1163,17 +1163,7 @@ impl CheckAttrVisitor<'_> { } /// Warns against some misuses of `#[must_use]` - fn check_must_use(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool { - let node = self.tcx.hir().get(hir_id); - if let Some(kind) = node.fn_kind() && let rustc_hir::IsAsync::Async = kind.asyncness() { - self.tcx.emit_spanned_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::MustUseAsync { span } - ); - } - + fn check_must_use(&self, hir_id: HirId, attr: &Attribute, target: Target) -> bool { if !matches!( target, Target::Fn diff --git a/src/test/ui/lint/unused/unused-async.rs b/src/test/ui/lint/unused/unused-async.rs index 7d17af1157379..eda28dab27fac 100644 --- a/src/test/ui/lint/unused/unused-async.rs +++ b/src/test/ui/lint/unused/unused-async.rs @@ -1,24 +1,43 @@ // edition:2018 -// run-pass -#![allow(dead_code)] +#![deny(unused_must_use)] + #[must_use] -//~^ WARNING `must_use` -async fn test() -> i32 { +async fn foo() -> i32 { 1 } +#[must_use] +fn bar() -> impl std::future::Future { + async { + 42 + } +} + +async fn baz() -> i32 { + 0 +} struct Wowee {} impl Wowee { #[must_use] - //~^ WARNING `must_use` async fn test_method() -> i32 { 1 } } +async fn test() { + foo(); //~ ERROR unused return value of `foo` that must be used + //~^ ERROR unused implementer of `Future` that must be used + foo().await; //~ ERROR unused awaited future returned by `foo` that must be used + bar(); //~ ERROR unused return value of `bar` that must be used + //~^ ERROR unused implementer of `Future` that must be used + bar().await; //~ ERROR unused awaited future returned by `bar` that must be used + baz(); //~ ERROR unused implementer of `Future` that must be used + baz().await; // ok +} + /* FIXME(guswynn) update this test when async-fn-in-traits works trait Doer { #[must_use] diff --git a/src/test/ui/lint/unused/unused-async.stderr b/src/test/ui/lint/unused/unused-async.stderr index 6bbc9e2bf0088..ae284681720af 100644 --- a/src/test/ui/lint/unused/unused-async.stderr +++ b/src/test/ui/lint/unused/unused-async.stderr @@ -1,26 +1,55 @@ -warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within - --> $DIR/unused-async.rs:5:1 - | -LL | #[must_use] - | ^^^^^^^^^^^ -LL | -LL | / async fn test() -> i32 { -LL | | 1 -LL | | } - | |_- this attribute does nothing, the `Future`s returned by async functions are already `must_use` - | - = note: `#[warn(unused_attributes)]` on by default - -warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within - --> $DIR/unused-async.rs:15:5 - | -LL | #[must_use] - | ^^^^^^^^^^^ -LL | -LL | / async fn test_method() -> i32 { -LL | | 1 -LL | | } - | |_____- this attribute does nothing, the `Future`s returned by async functions are already `must_use` - -warning: 2 warnings emitted +error: unused implementer of `Future` that must be used + --> $DIR/unused-async.rs:31:5 + | +LL | foo(); + | ^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-async.rs:2:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + = note: futures do nothing unless you `.await` or poll them + +error: unused return value of `foo` that must be used + --> $DIR/unused-async.rs:31:5 + | +LL | foo(); + | ^^^^^ + +error: unused awaited future returned by `foo` that must be used + --> $DIR/unused-async.rs:33:5 + | +LL | foo().await; + | ^^^^^^^^^^^ + +error: unused implementer of `Future` that must be used + --> $DIR/unused-async.rs:34:5 + | +LL | bar(); + | ^^^^^ + | + = note: futures do nothing unless you `.await` or poll them + +error: unused return value of `bar` that must be used + --> $DIR/unused-async.rs:34:5 + | +LL | bar(); + | ^^^^^ + +error: unused awaited future returned by `bar` that must be used + --> $DIR/unused-async.rs:36:5 + | +LL | bar().await; + | ^^^^^^^^^^^ + +error: unused implementer of `Future` that must be used + --> $DIR/unused-async.rs:37:5 + | +LL | baz(); + | ^^^^^ + | + = note: futures do nothing unless you `.await` or poll them + +error: aborting due to 7 previous errors From 8bd8484972ccfb4134c39b93c6ec68406bd1e63e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 17 Aug 2022 08:21:43 -0700 Subject: [PATCH 3/4] review comments --- compiler/rustc_lint/src/unused.rs | 13 ++++++++++--- src/test/ui/lint/unused/unused-async.rs | 4 ++-- src/test/ui/lint/unused/unused-async.stderr | 4 ++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 1a5515530ae9f..045d76cac62b8 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -95,10 +95,17 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { if let hir::ExprKind::Match(await_expr, _arms, hir::MatchSource::AwaitDesugar) = expr.kind && let ty = cx.typeck_results().expr_ty(&await_expr) - && let ty::Opaque(def_id, _) = ty.kind() + && let ty::Opaque(future_def_id, _) = ty.kind() && cx.tcx.ty_is_opaque_future(ty) - && let parent = cx.tcx.parent(*def_id) - && check_must_use_def(cx, parent, expr.span, "awaited future returned by ", "") + // FIXME: This also includes non-async fns that return `impl Future`. + && let async_fn_def_id = cx.tcx.parent(*future_def_id) + && check_must_use_def( + cx, + async_fn_def_id, + expr.span, + "output of future returned by ", + "", + ) { // We have a bare `foo().await;` on an opaque type from an async function that was // annotated with `#[must_use]`. diff --git a/src/test/ui/lint/unused/unused-async.rs b/src/test/ui/lint/unused/unused-async.rs index eda28dab27fac..4be93aa155ad9 100644 --- a/src/test/ui/lint/unused/unused-async.rs +++ b/src/test/ui/lint/unused/unused-async.rs @@ -30,10 +30,10 @@ impl Wowee { async fn test() { foo(); //~ ERROR unused return value of `foo` that must be used //~^ ERROR unused implementer of `Future` that must be used - foo().await; //~ ERROR unused awaited future returned by `foo` that must be used + foo().await; //~ ERROR unused output of future returned by `foo` that must be used bar(); //~ ERROR unused return value of `bar` that must be used //~^ ERROR unused implementer of `Future` that must be used - bar().await; //~ ERROR unused awaited future returned by `bar` that must be used + bar().await; //~ ERROR unused output of future returned by `bar` that must be used baz(); //~ ERROR unused implementer of `Future` that must be used baz().await; // ok } diff --git a/src/test/ui/lint/unused/unused-async.stderr b/src/test/ui/lint/unused/unused-async.stderr index ae284681720af..abc49599309ca 100644 --- a/src/test/ui/lint/unused/unused-async.stderr +++ b/src/test/ui/lint/unused/unused-async.stderr @@ -17,7 +17,7 @@ error: unused return value of `foo` that must be used LL | foo(); | ^^^^^ -error: unused awaited future returned by `foo` that must be used +error: unused output of future returned by `foo` that must be used --> $DIR/unused-async.rs:33:5 | LL | foo().await; @@ -37,7 +37,7 @@ error: unused return value of `bar` that must be used LL | bar(); | ^^^^^ -error: unused awaited future returned by `bar` that must be used +error: unused output of future returned by `bar` that must be used --> $DIR/unused-async.rs:36:5 | LL | bar().await; From f57713b010775afd4061a7bd03c8be3c90465e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 10 Nov 2022 19:01:33 -0800 Subject: [PATCH 4/4] Fix tests after rebase --- src/test/ui/lint/unused/unused-async.stderr | 2 +- src/test/ui/lint/unused/unused-supertrait.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/lint/unused/unused-async.stderr b/src/test/ui/lint/unused/unused-async.stderr index abc49599309ca..4bcb26dc16586 100644 --- a/src/test/ui/lint/unused/unused-async.stderr +++ b/src/test/ui/lint/unused/unused-async.stderr @@ -4,12 +4,12 @@ error: unused implementer of `Future` that must be used LL | foo(); | ^^^^^ | + = note: futures do nothing unless you `.await` or poll them note: the lint level is defined here --> $DIR/unused-async.rs:2:9 | LL | #![deny(unused_must_use)] | ^^^^^^^^^^^^^^^ - = note: futures do nothing unless you `.await` or poll them error: unused return value of `foo` that must be used --> $DIR/unused-async.rs:31:5 diff --git a/src/test/ui/lint/unused/unused-supertrait.stderr b/src/test/ui/lint/unused/unused-supertrait.stderr index d2f8c00784817..cb45add9c2b1b 100644 --- a/src/test/ui/lint/unused/unused-supertrait.stderr +++ b/src/test/ui/lint/unused/unused-supertrait.stderr @@ -2,7 +2,7 @@ error: unused implementer of `Iterator` that must be used --> $DIR/unused-supertrait.rs:9:5 | LL | it(); - | ^^^^^ + | ^^^^ | = note: iterators are lazy and do nothing unless consumed note: the lint level is defined here