From 821d50aa0cc73c1ec2fb09bab8a69e1c3ca93f23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 28 Jul 2020 00:00:00 +0000 Subject: [PATCH] Make closures and generators a must use types Warn about unused expressions with closure or generator type. This follows existing precedence of must use annotations present on `FnOnce`, `FnMut`, `Fn` traits, which already indirectly apply to closures in some cases, e.g.,: ```rust fn f() -> impl FnOnce() { || {} } fn main() { // an existing warning: unused implementer of `std::ops::FnOnce` that must be used: f(); // a new warning: unused closure that must be used: || {}; } ``` --- src/librustc_lint/unused.rs | 22 ++++++ src/test/ui/generator/issue-52398.rs | 4 +- src/test/ui/generator/issue-52398.stderr | 24 ++++++ src/test/ui/generator/issue-57084.rs | 2 +- src/test/ui/generator/issue-57084.stderr | 16 ++++ src/test/ui/generator/match-bindings.rs | 2 +- src/test/ui/generator/match-bindings.stderr | 17 +++++ src/test/ui/generator/reborrow-mut-upvar.rs | 2 +- .../ui/generator/reborrow-mut-upvar.stderr | 17 +++++ .../too-live-local-in-immovable-gen.rs | 2 +- .../too-live-local-in-immovable-gen.stderr | 17 +++++ src/test/ui/generator/yield-in-args-rev.rs | 2 +- .../ui/generator/yield-in-args-rev.stderr | 14 ++++ src/test/ui/generator/yield-in-box.rs | 2 +- src/test/ui/generator/yield-in-box.stderr | 17 +++++ src/test/ui/generator/yield-in-initializer.rs | 2 +- .../ui/generator/yield-in-initializer.stderr | 17 +++++ src/test/ui/generator/yield-subtype.rs | 2 +- src/test/ui/generator/yield-subtype.stderr | 14 ++++ src/test/ui/issues/issue-1460.rs | 2 +- src/test/ui/issues/issue-1460.stderr | 11 +++ src/test/ui/issues/issue-16256.rs | 2 +- src/test/ui/issues/issue-16256.stderr | 11 +++ src/test/ui/liveness/liveness-upvars.rs | 18 ++--- src/test/ui/nll/capture-mut-ref.fixed | 2 +- src/test/ui/nll/capture-mut-ref.rs | 2 +- src/test/ui/nll/issue-48623-generator.rs | 2 +- src/test/ui/nll/issue-48623-generator.stderr | 11 +++ .../test-runner-hides-buried-main.rs | 4 +- .../unboxed-closures-move-mutable.rs | 1 + .../unboxed-closures-move-mutable.stderr | 4 +- src/test/ui/unused/unused-closure.rs | 40 ++++++++++ src/test/ui/unused/unused-closure.stderr | 75 +++++++++++++++++++ .../unused-mut-warning-captured-var.fixed | 2 +- .../unused/unused-mut-warning-captured-var.rs | 2 +- src/test/ui/weird-exprs.rs | 2 +- 36 files changed, 355 insertions(+), 31 deletions(-) create mode 100644 src/test/ui/generator/issue-52398.stderr create mode 100644 src/test/ui/generator/issue-57084.stderr create mode 100644 src/test/ui/generator/match-bindings.stderr create mode 100644 src/test/ui/generator/reborrow-mut-upvar.stderr create mode 100644 src/test/ui/generator/too-live-local-in-immovable-gen.stderr create mode 100644 src/test/ui/generator/yield-in-args-rev.stderr create mode 100644 src/test/ui/generator/yield-in-box.stderr create mode 100644 src/test/ui/generator/yield-in-initializer.stderr create mode 100644 src/test/ui/generator/yield-subtype.stderr create mode 100644 src/test/ui/issues/issue-1460.stderr create mode 100644 src/test/ui/issues/issue-16256.stderr create mode 100644 src/test/ui/nll/issue-48623-generator.stderr create mode 100644 src/test/ui/unused/unused-closure.rs create mode 100644 src/test/ui/unused/unused-closure.stderr diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index dcb44ab6444..8d8fb8c3c60 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -203,6 +203,28 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { // Otherwise, we don't lint, to avoid false positives. _ => false, }, + ty::Closure(..) => { + cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| { + let mut err = lint.build(&format!( + "unused {}closure{}{} that must be used", + descr_pre, plural_suffix, descr_post, + )); + err.note("closures are lazy and do nothing unless called"); + err.emit(); + }); + true + } + ty::Generator(..) => { + cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| { + let mut err = lint.build(&format!( + "unused {}generator{}{} that must be used", + descr_pre, plural_suffix, descr_post, + )); + err.note("generators are lazy and do nothing unless resumed"); + err.emit(); + }); + true + } _ => false, } } diff --git a/src/test/ui/generator/issue-52398.rs b/src/test/ui/generator/issue-52398.rs index 54a1912582c..ada380d116c 100644 --- a/src/test/ui/generator/issue-52398.rs +++ b/src/test/ui/generator/issue-52398.rs @@ -14,14 +14,14 @@ impl A { fn main() { // Test that the MIR local with type &A created for the auto-borrow adjustment // is caught by typeck - move || { + move || { //~ WARN unused generator that must be used A.test(yield); }; // Test that the std::cell::Ref temporary returned from the `borrow` call // is caught by typeck let y = RefCell::new(true); - static move || { + static move || { //~ WARN unused generator that must be used yield *y.borrow(); return "Done"; }; diff --git a/src/test/ui/generator/issue-52398.stderr b/src/test/ui/generator/issue-52398.stderr new file mode 100644 index 00000000000..3f8ebb5a738 --- /dev/null +++ b/src/test/ui/generator/issue-52398.stderr @@ -0,0 +1,24 @@ +warning: unused generator that must be used + --> $DIR/issue-52398.rs:17:5 + | +LL | / move || { +LL | | A.test(yield); +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: unused generator that must be used + --> $DIR/issue-52398.rs:24:5 + | +LL | / static move || { +LL | | yield *y.borrow(); +LL | | return "Done"; +LL | | }; + | |______^ + | + = note: generators are lazy and do nothing unless resumed + +warning: 2 warnings emitted + diff --git a/src/test/ui/generator/issue-57084.rs b/src/test/ui/generator/issue-57084.rs index 8aaa6a0e427..2a5c3dd0570 100644 --- a/src/test/ui/generator/issue-57084.rs +++ b/src/test/ui/generator/issue-57084.rs @@ -19,7 +19,7 @@ where F: Fn() -> () fn main() { let data = &vec![1]; - || { + || { //~ WARN unused generator that must be used let _to_pin = with(move || println!("{:p}", data)); loop { yield diff --git a/src/test/ui/generator/issue-57084.stderr b/src/test/ui/generator/issue-57084.stderr new file mode 100644 index 00000000000..32a04f94dcb --- /dev/null +++ b/src/test/ui/generator/issue-57084.stderr @@ -0,0 +1,16 @@ +warning: unused generator that must be used + --> $DIR/issue-57084.rs:22:5 + | +LL | / || { +LL | | let _to_pin = with(move || println!("{:p}", data)); +LL | | loop { +LL | | yield +LL | | } +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/match-bindings.rs b/src/test/ui/generator/match-bindings.rs index 560d8e7103c..865904a57d4 100644 --- a/src/test/ui/generator/match-bindings.rs +++ b/src/test/ui/generator/match-bindings.rs @@ -9,7 +9,7 @@ enum Enum { } fn main() { - || { + || { //~ WARN unused generator that must be used loop { if let true = true { match Enum::A(String::new()) { diff --git a/src/test/ui/generator/match-bindings.stderr b/src/test/ui/generator/match-bindings.stderr new file mode 100644 index 00000000000..4fd1e26f0c8 --- /dev/null +++ b/src/test/ui/generator/match-bindings.stderr @@ -0,0 +1,17 @@ +warning: unused generator that must be used + --> $DIR/match-bindings.rs:12:5 + | +LL | / || { +LL | | loop { +LL | | if let true = true { +LL | | match Enum::A(String::new()) { +... | +LL | | } +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/reborrow-mut-upvar.rs b/src/test/ui/generator/reborrow-mut-upvar.rs index 785e38a7eb8..dbd9e24e205 100644 --- a/src/test/ui/generator/reborrow-mut-upvar.rs +++ b/src/test/ui/generator/reborrow-mut-upvar.rs @@ -3,7 +3,7 @@ #![feature(generators)] fn _run(bar: &mut i32) { - || { + || { //~ WARN unused generator that must be used { let _baz = &*bar; yield; diff --git a/src/test/ui/generator/reborrow-mut-upvar.stderr b/src/test/ui/generator/reborrow-mut-upvar.stderr new file mode 100644 index 00000000000..ff511b76672 --- /dev/null +++ b/src/test/ui/generator/reborrow-mut-upvar.stderr @@ -0,0 +1,17 @@ +warning: unused generator that must be used + --> $DIR/reborrow-mut-upvar.rs:6:5 + | +LL | / || { +LL | | { +LL | | let _baz = &*bar; +LL | | yield; +... | +LL | | *bar = 2; +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/too-live-local-in-immovable-gen.rs b/src/test/ui/generator/too-live-local-in-immovable-gen.rs index f299a8aa72b..7f118c88e5e 100644 --- a/src/test/ui/generator/too-live-local-in-immovable-gen.rs +++ b/src/test/ui/generator/too-live-local-in-immovable-gen.rs @@ -5,7 +5,7 @@ fn main() { unsafe { - static move || { + static move || { //~ WARN unused generator that must be used // Tests that the generator transformation finds out that `a` is not live // during the yield expression. Type checking will also compute liveness // and it should also find out that `a` is not live. 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 new file mode 100644 index 00000000000..88dacff7b55 --- /dev/null +++ b/src/test/ui/generator/too-live-local-in-immovable-gen.stderr @@ -0,0 +1,17 @@ +warning: unused generator that must be used + --> $DIR/too-live-local-in-immovable-gen.rs:8:9 + | +LL | / static move || { +LL | | // Tests that the generator transformation finds out that `a` is not live +LL | | // during the yield expression. Type checking will also compute liveness +LL | | // and it should also find out that `a` is not live. +... | +LL | | &a; +LL | | }; + | |__________^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/yield-in-args-rev.rs b/src/test/ui/generator/yield-in-args-rev.rs index f9ab981121a..4c99bb3ef5e 100644 --- a/src/test/ui/generator/yield-in-args-rev.rs +++ b/src/test/ui/generator/yield-in-args-rev.rs @@ -10,7 +10,7 @@ fn foo(_a: (), _b: &bool) {} fn bar() { - || { + || { //~ WARN unused generator that must be used let b = true; foo(yield, &b); }; diff --git a/src/test/ui/generator/yield-in-args-rev.stderr b/src/test/ui/generator/yield-in-args-rev.stderr new file mode 100644 index 00000000000..a575bf88678 --- /dev/null +++ b/src/test/ui/generator/yield-in-args-rev.stderr @@ -0,0 +1,14 @@ +warning: unused generator that must be used + --> $DIR/yield-in-args-rev.rs:13:5 + | +LL | / || { +LL | | let b = true; +LL | | foo(yield, &b); +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/yield-in-box.rs b/src/test/ui/generator/yield-in-box.rs index d8475715c7c..65f368df9cb 100644 --- a/src/test/ui/generator/yield-in-box.rs +++ b/src/test/ui/generator/yield-in-box.rs @@ -6,7 +6,7 @@ fn main() { let x = 0i32; - || { + || { //~ WARN unused generator that must be used let y = 2u32; { let _t = box (&x, yield 0, &y); diff --git a/src/test/ui/generator/yield-in-box.stderr b/src/test/ui/generator/yield-in-box.stderr new file mode 100644 index 00000000000..24de18edb0f --- /dev/null +++ b/src/test/ui/generator/yield-in-box.stderr @@ -0,0 +1,17 @@ +warning: unused generator that must be used + --> $DIR/yield-in-box.rs:9:5 + | +LL | / || { +LL | | let y = 2u32; +LL | | { +LL | | let _t = box (&x, yield 0, &y); +... | +LL | | } +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/yield-in-initializer.rs b/src/test/ui/generator/yield-in-initializer.rs index 8ff35d8ddf1..2f8754c9571 100644 --- a/src/test/ui/generator/yield-in-initializer.rs +++ b/src/test/ui/generator/yield-in-initializer.rs @@ -3,7 +3,7 @@ #![feature(generators)] fn main() { - static || { + static || { //~ WARN unused generator that must be used loop { // Test that `opt` is not live across the yield, even when borrowed in a loop // See https://github.com/rust-lang/rust/issues/52792 diff --git a/src/test/ui/generator/yield-in-initializer.stderr b/src/test/ui/generator/yield-in-initializer.stderr new file mode 100644 index 00000000000..e79047ae701 --- /dev/null +++ b/src/test/ui/generator/yield-in-initializer.stderr @@ -0,0 +1,17 @@ +warning: unused generator that must be used + --> $DIR/yield-in-initializer.rs:6:5 + | +LL | / static || { +LL | | loop { +LL | | // Test that `opt` is not live across the yield, even when borrowed in a loop +LL | | // See https://github.com/rust-lang/rust/issues/52792 +... | +LL | | } +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/yield-subtype.rs b/src/test/ui/generator/yield-subtype.rs index fe88d424dd1..cb3fc909145 100644 --- a/src/test/ui/generator/yield-subtype.rs +++ b/src/test/ui/generator/yield-subtype.rs @@ -8,7 +8,7 @@ fn bar<'a>() { let a: &'static str = "hi"; let b: &'a str = a; - || { + || { //~ WARN unused generator that must be used yield a; yield b; }; diff --git a/src/test/ui/generator/yield-subtype.stderr b/src/test/ui/generator/yield-subtype.stderr new file mode 100644 index 00000000000..bded36a4cda --- /dev/null +++ b/src/test/ui/generator/yield-subtype.stderr @@ -0,0 +1,14 @@ +warning: unused generator that must be used + --> $DIR/yield-subtype.rs:11:5 + | +LL | / || { +LL | | yield a; +LL | | yield b; +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/issues/issue-1460.rs b/src/test/ui/issues/issue-1460.rs index 143a0387e21..e663f7fd4c9 100644 --- a/src/test/ui/issues/issue-1460.rs +++ b/src/test/ui/issues/issue-1460.rs @@ -3,5 +3,5 @@ // pretty-expanded FIXME #23616 pub fn main() { - {|i: u32| if 1 == i { }}; + {|i: u32| if 1 == i { }}; //~ WARN unused closure that must be used } diff --git a/src/test/ui/issues/issue-1460.stderr b/src/test/ui/issues/issue-1460.stderr new file mode 100644 index 00000000000..26f95f5af3d --- /dev/null +++ b/src/test/ui/issues/issue-1460.stderr @@ -0,0 +1,11 @@ +warning: unused closure that must be used + --> $DIR/issue-1460.rs:6:5 + | +LL | {|i: u32| if 1 == i { }}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: closures are lazy and do nothing unless called + +warning: 1 warning emitted + diff --git a/src/test/ui/issues/issue-16256.rs b/src/test/ui/issues/issue-16256.rs index e566eede8d2..eec23437bcb 100644 --- a/src/test/ui/issues/issue-16256.rs +++ b/src/test/ui/issues/issue-16256.rs @@ -3,5 +3,5 @@ fn main() { let mut buf = Vec::new(); - |c: u8| buf.push(c); + |c: u8| buf.push(c); //~ WARN unused closure that must be used } diff --git a/src/test/ui/issues/issue-16256.stderr b/src/test/ui/issues/issue-16256.stderr new file mode 100644 index 00000000000..9c7312461c4 --- /dev/null +++ b/src/test/ui/issues/issue-16256.stderr @@ -0,0 +1,11 @@ +warning: unused closure that must be used + --> $DIR/issue-16256.rs:6:5 + | +LL | |c: u8| buf.push(c); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: closures are lazy and do nothing unless called + +warning: 1 warning emitted + diff --git a/src/test/ui/liveness/liveness-upvars.rs b/src/test/ui/liveness/liveness-upvars.rs index b2837e74b8c..98ea4d71ccf 100644 --- a/src/test/ui/liveness/liveness-upvars.rs +++ b/src/test/ui/liveness/liveness-upvars.rs @@ -27,7 +27,7 @@ pub fn f() { let mut c = 0; // Captured by value, but variable is dead on entry. - move || { + let _ = move || { c = 1; //~ WARN value captured by `c` is never read println!("{}", c); }; @@ -37,7 +37,7 @@ pub fn f() { }; // Read and written to, but never actually used. - move || { + let _ = move || { c += 1; //~ WARN unused variable: `c` }; let _ = async move { @@ -45,13 +45,13 @@ pub fn f() { //~| WARN unused variable: `c` }; - move || { + let _ = move || { println!("{}", c); // Value is read by closure itself on later invocations. c += 1; }; let b = Box::new(42); - move || { + let _ = move || { println!("{}", c); // Never read because this is FnOnce closure. c += 1; //~ WARN value assigned to `c` is never read @@ -67,12 +67,12 @@ pub fn f() { pub fn nested() { let mut d = None; let mut e = None; - || { - || { + let _ = || { + let _ = || { d = Some("d1"); //~ WARN value assigned to `d` is never read d = Some("d2"); }; - move || { + let _ = move || { e = Some("e1"); //~ WARN value assigned to `e` is never read //~| WARN unused variable: `e` e = Some("e2"); //~ WARN value assigned to `e` is never read @@ -81,7 +81,7 @@ pub fn nested() { } pub fn g(mut v: T) { - |r| { + let _ = |r| { if r { v = T::default(); //~ WARN value assigned to `v` is never read } else { @@ -92,7 +92,7 @@ pub fn g(mut v: T) { pub fn h() { let mut z = T::default(); - move |b| { + let _ = move |b| { loop { if b { z = T::default(); //~ WARN value assigned to `z` is never read diff --git a/src/test/ui/nll/capture-mut-ref.fixed b/src/test/ui/nll/capture-mut-ref.fixed index 639de2813a9..2dacb26b6eb 100644 --- a/src/test/ui/nll/capture-mut-ref.fixed +++ b/src/test/ui/nll/capture-mut-ref.fixed @@ -8,7 +8,7 @@ pub fn mutable_upvar() { let x = &mut 0; //~^ ERROR - move || { + let _ = move || { *x = 1; }; } diff --git a/src/test/ui/nll/capture-mut-ref.rs b/src/test/ui/nll/capture-mut-ref.rs index 89f49e1ea51..56e01f7b776 100644 --- a/src/test/ui/nll/capture-mut-ref.rs +++ b/src/test/ui/nll/capture-mut-ref.rs @@ -8,7 +8,7 @@ pub fn mutable_upvar() { let mut x = &mut 0; //~^ ERROR - move || { + let _ = move || { *x = 1; }; } diff --git a/src/test/ui/nll/issue-48623-generator.rs b/src/test/ui/nll/issue-48623-generator.rs index ba3eccff495..08d2584ee5e 100644 --- a/src/test/ui/nll/issue-48623-generator.rs +++ b/src/test/ui/nll/issue-48623-generator.rs @@ -12,7 +12,7 @@ impl Drop for WithDrop { fn reborrow_from_generator(r: &mut ()) { let d = WithDrop; - move || { d; yield; &mut *r }; + move || { d; yield; &mut *r }; //~ WARN unused generator that must be used } fn main() {} diff --git a/src/test/ui/nll/issue-48623-generator.stderr b/src/test/ui/nll/issue-48623-generator.stderr new file mode 100644 index 00000000000..70a83e46ff0 --- /dev/null +++ b/src/test/ui/nll/issue-48623-generator.stderr @@ -0,0 +1,11 @@ +warning: unused generator that must be used + --> $DIR/issue-48623-generator.rs:15:5 + | +LL | move || { d; yield; &mut *r }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/test-attrs/test-runner-hides-buried-main.rs b/src/test/ui/test-attrs/test-runner-hides-buried-main.rs index 917c09801e1..bf5482056d4 100644 --- a/src/test/ui/test-attrs/test-runner-hides-buried-main.rs +++ b/src/test/ui/test-attrs/test-runner-hides-buried-main.rs @@ -7,9 +7,9 @@ mod a { fn b() { - || { + (|| { #[main] fn c() { panic!(); } - }; + })(); } } diff --git a/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs index e5b19db7822..470904fd391 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs @@ -2,6 +2,7 @@ // pretty-expanded FIXME #23616 #![deny(unused_mut)] +#![allow(unused_must_use)] // Test that mutating a mutable upvar in a capture-by-value unboxed // closure does not ice (issue #18238) and marks the upvar as used diff --git a/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr index 4dfd1bb3075..1254f8dbc5e 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr @@ -1,5 +1,5 @@ warning: unused variable: `x` - --> $DIR/unboxed-closures-move-mutable.rs:16:17 + --> $DIR/unboxed-closures-move-mutable.rs:17:17 | LL | move || x += 1; | ^ @@ -8,7 +8,7 @@ LL | move || x += 1; = help: did you mean to capture by reference instead? warning: unused variable: `x` - --> $DIR/unboxed-closures-move-mutable.rs:20:17 + --> $DIR/unboxed-closures-move-mutable.rs:21:17 | LL | move || x += 1; | ^ diff --git a/src/test/ui/unused/unused-closure.rs b/src/test/ui/unused/unused-closure.rs new file mode 100644 index 00000000000..637d8bb43a7 --- /dev/null +++ b/src/test/ui/unused/unused-closure.rs @@ -0,0 +1,40 @@ +// Test that closures and generators are "must use" types. +// edition:2018 + +#![feature(async_closure)] +#![feature(const_in_array_repeat_expressions)] +#![feature(generators)] +#![deny(unused_must_use)] + +fn unused() { + || { //~ ERROR unused closure that must be used + println!("Hello!"); + }; + + async {}; //~ ERROR unused implementer of `std::future::Future` that must be used + || async {}; //~ ERROR unused closure that must be used + async || {}; //~ ERROR unused closure that must be used + + + [Box::new([|| {}; 10]); 1]; //~ ERROR unused array of boxed arrays of closures that must be used + + [|| { //~ ERROR unused array of generators that must be used + yield 42u32; + }; 42]; + + vec![|| "a"].pop().unwrap(); //~ ERROR unused closure that must be used + + let b = false; + || true; //~ ERROR unused closure that must be used + println!("{}", b); +} + +fn ignored() { + let _ = || {}; + let _ = || yield 42; +} + +fn main() { + unused(); + ignored(); +} diff --git a/src/test/ui/unused/unused-closure.stderr b/src/test/ui/unused/unused-closure.stderr new file mode 100644 index 00000000000..9dc73fb7abe --- /dev/null +++ b/src/test/ui/unused/unused-closure.stderr @@ -0,0 +1,75 @@ +error: unused closure that must be used + --> $DIR/unused-closure.rs:10:5 + | +LL | / || { +LL | | println!("Hello!"); +LL | | }; + | |______^ + | +note: the lint level is defined here + --> $DIR/unused-closure.rs:7:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + = note: closures are lazy and do nothing unless called + +error: unused implementer of `std::future::Future` that must be used + --> $DIR/unused-closure.rs:14:5 + | +LL | async {}; + | ^^^^^^^^^ + | + = note: futures do nothing unless you `.await` or poll them + +error: unused closure that must be used + --> $DIR/unused-closure.rs:15:5 + | +LL | || async {}; + | ^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused closure that must be used + --> $DIR/unused-closure.rs:16:5 + | +LL | async || {}; + | ^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused array of boxed arrays of closures that must be used + --> $DIR/unused-closure.rs:19:5 + | +LL | [Box::new([|| {}; 10]); 1]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused array of generators that must be used + --> $DIR/unused-closure.rs:21:5 + | +LL | / [|| { +LL | | yield 42u32; +LL | | }; 42]; + | |___________^ + | + = note: generators are lazy and do nothing unless resumed + +error: unused closure that must be used + --> $DIR/unused-closure.rs:25:5 + | +LL | vec![|| "a"].pop().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused closure that must be used + --> $DIR/unused-closure.rs:28:9 + | +LL | || true; + | ^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: aborting due to 8 previous errors + diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.fixed b/src/test/ui/unused/unused-mut-warning-captured-var.fixed index b67b2a7259b..c21f18015c1 100644 --- a/src/test/ui/unused/unused-mut-warning-captured-var.fixed +++ b/src/test/ui/unused/unused-mut-warning-captured-var.fixed @@ -5,5 +5,5 @@ fn main() { let x = 1; //~^ ERROR: variable does not need to be mutable - move|| { println!("{}", x); }; + (move|| { println!("{}", x); })(); } diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.rs b/src/test/ui/unused/unused-mut-warning-captured-var.rs index 8726c4f173f..3119d83a0eb 100644 --- a/src/test/ui/unused/unused-mut-warning-captured-var.rs +++ b/src/test/ui/unused/unused-mut-warning-captured-var.rs @@ -5,5 +5,5 @@ fn main() { let mut x = 1; //~^ ERROR: variable does not need to be mutable - move|| { println!("{}", x); }; + (move|| { println!("{}", x); })(); } diff --git a/src/test/ui/weird-exprs.rs b/src/test/ui/weird-exprs.rs index d812bbd011e..916cabbfb8c 100644 --- a/src/test/ui/weird-exprs.rs +++ b/src/test/ui/weird-exprs.rs @@ -5,7 +5,7 @@ #![allow(non_camel_case_types)] #![allow(dead_code)] #![allow(unreachable_code)] -#![allow(unused_braces, unused_parens)] +#![allow(unused_braces, unused_must_use, unused_parens)] #![recursion_limit = "256"]