about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/doc/unstable-book/src/language-features/plugin.md2
-rw-r--r--src/librustc_lint/unused.rs22
-rw-r--r--src/librustc_symbol_mangling/v0.rs4
-rw-r--r--src/librustc_target/spec/thumbv4t_none_eabi.rs2
-rw-r--r--src/librustdoc/clean/auto_trait.rs8
-rw-r--r--src/test/ui/generator/issue-52398.rs4
-rw-r--r--src/test/ui/generator/issue-52398.stderr24
-rw-r--r--src/test/ui/generator/issue-57084.rs2
-rw-r--r--src/test/ui/generator/issue-57084.stderr16
-rw-r--r--src/test/ui/generator/match-bindings.rs2
-rw-r--r--src/test/ui/generator/match-bindings.stderr17
-rw-r--r--src/test/ui/generator/reborrow-mut-upvar.rs2
-rw-r--r--src/test/ui/generator/reborrow-mut-upvar.stderr17
-rw-r--r--src/test/ui/generator/too-live-local-in-immovable-gen.rs2
-rw-r--r--src/test/ui/generator/too-live-local-in-immovable-gen.stderr17
-rw-r--r--src/test/ui/generator/yield-in-args-rev.rs2
-rw-r--r--src/test/ui/generator/yield-in-args-rev.stderr14
-rw-r--r--src/test/ui/generator/yield-in-box.rs2
-rw-r--r--src/test/ui/generator/yield-in-box.stderr17
-rw-r--r--src/test/ui/generator/yield-in-initializer.rs2
-rw-r--r--src/test/ui/generator/yield-in-initializer.stderr17
-rw-r--r--src/test/ui/generator/yield-subtype.rs2
-rw-r--r--src/test/ui/generator/yield-subtype.stderr14
-rw-r--r--src/test/ui/issues/issue-1460.rs2
-rw-r--r--src/test/ui/issues/issue-1460.stderr11
-rw-r--r--src/test/ui/issues/issue-16256.rs2
-rw-r--r--src/test/ui/issues/issue-16256.stderr11
-rw-r--r--src/test/ui/liveness/liveness-upvars.rs18
-rw-r--r--src/test/ui/nll/capture-mut-ref.fixed2
-rw-r--r--src/test/ui/nll/capture-mut-ref.rs2
-rw-r--r--src/test/ui/nll/issue-48623-generator.rs2
-rw-r--r--src/test/ui/nll/issue-48623-generator.stderr11
-rw-r--r--src/test/ui/test-attrs/test-runner-hides-buried-main.rs4
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs1
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr4
-rw-r--r--src/test/ui/unused/unused-closure.rs40
-rw-r--r--src/test/ui/unused/unused-closure.stderr75
-rw-r--r--src/test/ui/unused/unused-mut-warning-captured-var.fixed2
-rw-r--r--src/test/ui/unused/unused-mut-warning-captured-var.rs2
-rw-r--r--src/test/ui/weird-exprs.rs2
40 files changed, 362 insertions, 40 deletions
diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md
index 47ac986c224..1f010656bb8 100644
--- a/src/doc/unstable-book/src/language-features/plugin.md
+++ b/src/doc/unstable-book/src/language-features/plugin.md
@@ -35,7 +35,7 @@ of a library.
 Plugins can extend [Rust's lint
 infrastructure](../../reference/attributes/diagnostics.md#lint-check-attributes) with
 additional checks for code style, safety, etc. Now let's write a plugin
-[`lint_plugin_test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs)
+[`lint-plugin-test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs)
 that warns about any item named `lintme`.
 
 ```rust,ignore
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/librustc_symbol_mangling/v0.rs b/src/librustc_symbol_mangling/v0.rs
index ecf27fbf542..676fee590b3 100644
--- a/src/librustc_symbol_mangling/v0.rs
+++ b/src/librustc_symbol_mangling/v0.rs
@@ -636,9 +636,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
                 }
                 GenericArgKind::Const(c) => {
                     self.push("K");
-                    // FIXME(const_generics) implement `ty::print::Print` on `ty::Const`.
-                    // self = c.print(self)?;
-                    self = self.print_const(c)?;
+                    self = c.print(self)?;
                 }
             }
         }
diff --git a/src/librustc_target/spec/thumbv4t_none_eabi.rs b/src/librustc_target/spec/thumbv4t_none_eabi.rs
index 31417b01547..a8c78f057fc 100644
--- a/src/librustc_target/spec/thumbv4t_none_eabi.rs
+++ b/src/librustc_target/spec/thumbv4t_none_eabi.rs
@@ -29,7 +29,7 @@ pub fn target() -> TargetResult {
          * native integers are 32-bit
          * All other elements are default
          */
-        data_layout: "e-S64-p:32:32-i64:64-m:e-n32".to_string(),
+        data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         linker_flavor: LinkerFlavor::Ld,
         options: TargetOptions {
             linker: Some("arm-none-eabi-ld".to_string()),
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 98d8f100b27..b170b413146 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -430,14 +430,14 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
     }
 
     // Converts the calculated ParamEnv and lifetime information to a clean::Generics, suitable for
-    // display on the docs page. Cleaning the Predicates produces sub-optimal WherePredicate's,
+    // display on the docs page. Cleaning the Predicates produces sub-optimal `WherePredicate`s,
     // so we fix them up:
     //
     // * Multiple bounds for the same type are coalesced into one: e.g., 'T: Copy', 'T: Debug'
     // becomes 'T: Copy + Debug'
     // * Fn bounds are handled specially - instead of leaving it as 'T: Fn(), <T as Fn::Output> =
     // K', we use the dedicated syntax 'T: Fn() -> K'
-    // * We explcitly add a '?Sized' bound if we didn't find any 'Sized' predicates for a type
+    // * We explicitly add a '?Sized' bound if we didn't find any 'Sized' predicates for a type
     fn param_env_to_generics(
         &self,
         tcx: TyCtxt<'tcx>,
@@ -588,7 +588,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                                         .args;
 
                                     match args {
-                                        // Convert somethiung like '<T as Iterator::Item> = u8'
+                                        // Convert something like '<T as Iterator::Item> = u8'
                                         // to 'T: Iterator<Item=u8>'
                                         GenericArgs::AngleBracketed {
                                             ref mut bindings, ..
@@ -712,7 +712,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
     // since FxHasher has different behavior for 32-bit and 64-bit platforms.
     //
     // Obviously, it's extremely undesirable for documentation rendering
-    // to be depndent on the platform it's run on. Apart from being confusing
+    // to be dependent on the platform it's run on. Apart from being confusing
     // to end users, it makes writing tests much more difficult, as predicates
     // can appear in any order in the final result.
     //
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<T: Default>(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<T: Default>(mut v: T) {
 
 pub fn h<T: Copy + Default + std::fmt::Debug>() {
     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"]