Rollup merge of #74869 - tmiasko:must-use-closures, r=ecstatic-morse
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: || {}; } ``` Closes #74691.
This commit is contained in:
commit
4230f96bbe
@ -203,6 +203,28 @@ fn check_must_use_ty<'tcx>(
|
|||||||
// Otherwise, we don't lint, to avoid false positives.
|
// Otherwise, we don't lint, to avoid false positives.
|
||||||
_ => false,
|
_ => 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,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,14 +14,14 @@ fn test(&self, a: ()) {}
|
|||||||
fn main() {
|
fn main() {
|
||||||
// Test that the MIR local with type &A created for the auto-borrow adjustment
|
// Test that the MIR local with type &A created for the auto-borrow adjustment
|
||||||
// is caught by typeck
|
// is caught by typeck
|
||||||
move || {
|
move || { //~ WARN unused generator that must be used
|
||||||
A.test(yield);
|
A.test(yield);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test that the std::cell::Ref temporary returned from the `borrow` call
|
// Test that the std::cell::Ref temporary returned from the `borrow` call
|
||||||
// is caught by typeck
|
// is caught by typeck
|
||||||
let y = RefCell::new(true);
|
let y = RefCell::new(true);
|
||||||
static move || {
|
static move || { //~ WARN unused generator that must be used
|
||||||
yield *y.borrow();
|
yield *y.borrow();
|
||||||
return "Done";
|
return "Done";
|
||||||
};
|
};
|
||||||
|
24
src/test/ui/generator/issue-52398.stderr
Normal file
24
src/test/ui/generator/issue-52398.stderr
Normal file
@ -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
|
||||||
|
|
@ -19,7 +19,7 @@ fn with<F>(f: F) -> impl Generator<Yield=(), Return=()>
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let data = &vec![1];
|
let data = &vec![1];
|
||||||
|| {
|
|| { //~ WARN unused generator that must be used
|
||||||
let _to_pin = with(move || println!("{:p}", data));
|
let _to_pin = with(move || println!("{:p}", data));
|
||||||
loop {
|
loop {
|
||||||
yield
|
yield
|
||||||
|
16
src/test/ui/generator/issue-57084.stderr
Normal file
16
src/test/ui/generator/issue-57084.stderr
Normal file
@ -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
|
||||||
|
|
@ -9,7 +9,7 @@ enum Enum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|| {
|
|| { //~ WARN unused generator that must be used
|
||||||
loop {
|
loop {
|
||||||
if let true = true {
|
if let true = true {
|
||||||
match Enum::A(String::new()) {
|
match Enum::A(String::new()) {
|
||||||
|
17
src/test/ui/generator/match-bindings.stderr
Normal file
17
src/test/ui/generator/match-bindings.stderr
Normal file
@ -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
|
||||||
|
|
@ -3,7 +3,7 @@
|
|||||||
#![feature(generators)]
|
#![feature(generators)]
|
||||||
|
|
||||||
fn _run(bar: &mut i32) {
|
fn _run(bar: &mut i32) {
|
||||||
|| {
|
|| { //~ WARN unused generator that must be used
|
||||||
{
|
{
|
||||||
let _baz = &*bar;
|
let _baz = &*bar;
|
||||||
yield;
|
yield;
|
||||||
|
17
src/test/ui/generator/reborrow-mut-upvar.stderr
Normal file
17
src/test/ui/generator/reborrow-mut-upvar.stderr
Normal file
@ -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
|
||||||
|
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
static move || {
|
static move || { //~ WARN unused generator that must be used
|
||||||
// Tests that the generator transformation finds out that `a` is not live
|
// Tests that the generator transformation finds out that `a` is not live
|
||||||
// during the yield expression. Type checking will also compute liveness
|
// during the yield expression. Type checking will also compute liveness
|
||||||
// and it should also find out that `a` is not live.
|
// and it should also find out that `a` is not live.
|
||||||
|
17
src/test/ui/generator/too-live-local-in-immovable-gen.stderr
Normal file
17
src/test/ui/generator/too-live-local-in-immovable-gen.stderr
Normal file
@ -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
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
fn foo(_a: (), _b: &bool) {}
|
fn foo(_a: (), _b: &bool) {}
|
||||||
|
|
||||||
fn bar() {
|
fn bar() {
|
||||||
|| {
|
|| { //~ WARN unused generator that must be used
|
||||||
let b = true;
|
let b = true;
|
||||||
foo(yield, &b);
|
foo(yield, &b);
|
||||||
};
|
};
|
||||||
|
14
src/test/ui/generator/yield-in-args-rev.stderr
Normal file
14
src/test/ui/generator/yield-in-args-rev.stderr
Normal file
@ -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
|
||||||
|
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = 0i32;
|
let x = 0i32;
|
||||||
|| {
|
|| { //~ WARN unused generator that must be used
|
||||||
let y = 2u32;
|
let y = 2u32;
|
||||||
{
|
{
|
||||||
let _t = box (&x, yield 0, &y);
|
let _t = box (&x, yield 0, &y);
|
||||||
|
17
src/test/ui/generator/yield-in-box.stderr
Normal file
17
src/test/ui/generator/yield-in-box.stderr
Normal file
@ -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
|
||||||
|
|
@ -3,7 +3,7 @@
|
|||||||
#![feature(generators)]
|
#![feature(generators)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
static || {
|
static || { //~ WARN unused generator that must be used
|
||||||
loop {
|
loop {
|
||||||
// Test that `opt` is not live across the yield, even when borrowed in a 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
|
// See https://github.com/rust-lang/rust/issues/52792
|
||||||
|
17
src/test/ui/generator/yield-in-initializer.stderr
Normal file
17
src/test/ui/generator/yield-in-initializer.stderr
Normal file
@ -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
|
||||||
|
|
@ -8,7 +8,7 @@ fn bar<'a>() {
|
|||||||
let a: &'static str = "hi";
|
let a: &'static str = "hi";
|
||||||
let b: &'a str = a;
|
let b: &'a str = a;
|
||||||
|
|
||||||
|| {
|
|| { //~ WARN unused generator that must be used
|
||||||
yield a;
|
yield a;
|
||||||
yield b;
|
yield b;
|
||||||
};
|
};
|
||||||
|
14
src/test/ui/generator/yield-subtype.stderr
Normal file
14
src/test/ui/generator/yield-subtype.stderr
Normal file
@ -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
|
||||||
|
|
@ -3,5 +3,5 @@
|
|||||||
// pretty-expanded FIXME #23616
|
// pretty-expanded FIXME #23616
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
{|i: u32| if 1 == i { }};
|
{|i: u32| if 1 == i { }}; //~ WARN unused closure that must be used
|
||||||
}
|
}
|
||||||
|
11
src/test/ui/issues/issue-1460.stderr
Normal file
11
src/test/ui/issues/issue-1460.stderr
Normal file
@ -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
|
||||||
|
|
@ -3,5 +3,5 @@
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
|c: u8| buf.push(c);
|
|c: u8| buf.push(c); //~ WARN unused closure that must be used
|
||||||
}
|
}
|
||||||
|
11
src/test/ui/issues/issue-16256.stderr
Normal file
11
src/test/ui/issues/issue-16256.stderr
Normal file
@ -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
|
||||||
|
|
@ -27,7 +27,7 @@ pub fn f() {
|
|||||||
let mut c = 0;
|
let mut c = 0;
|
||||||
|
|
||||||
// Captured by value, but variable is dead on entry.
|
// Captured by value, but variable is dead on entry.
|
||||||
move || {
|
let _ = move || {
|
||||||
c = 1; //~ WARN value captured by `c` is never read
|
c = 1; //~ WARN value captured by `c` is never read
|
||||||
println!("{}", c);
|
println!("{}", c);
|
||||||
};
|
};
|
||||||
@ -37,7 +37,7 @@ pub fn f() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Read and written to, but never actually used.
|
// Read and written to, but never actually used.
|
||||||
move || {
|
let _ = move || {
|
||||||
c += 1; //~ WARN unused variable: `c`
|
c += 1; //~ WARN unused variable: `c`
|
||||||
};
|
};
|
||||||
let _ = async move {
|
let _ = async move {
|
||||||
@ -45,13 +45,13 @@ pub fn f() {
|
|||||||
//~| WARN unused variable: `c`
|
//~| WARN unused variable: `c`
|
||||||
};
|
};
|
||||||
|
|
||||||
move || {
|
let _ = move || {
|
||||||
println!("{}", c);
|
println!("{}", c);
|
||||||
// Value is read by closure itself on later invocations.
|
// Value is read by closure itself on later invocations.
|
||||||
c += 1;
|
c += 1;
|
||||||
};
|
};
|
||||||
let b = Box::new(42);
|
let b = Box::new(42);
|
||||||
move || {
|
let _ = move || {
|
||||||
println!("{}", c);
|
println!("{}", c);
|
||||||
// Never read because this is FnOnce closure.
|
// Never read because this is FnOnce closure.
|
||||||
c += 1; //~ WARN value assigned to `c` is never read
|
c += 1; //~ WARN value assigned to `c` is never read
|
||||||
@ -67,12 +67,12 @@ pub fn f() {
|
|||||||
pub fn nested() {
|
pub fn nested() {
|
||||||
let mut d = None;
|
let mut d = None;
|
||||||
let mut e = None;
|
let mut e = None;
|
||||||
|| {
|
let _ = || {
|
||||||
|| {
|
let _ = || {
|
||||||
d = Some("d1"); //~ WARN value assigned to `d` is never read
|
d = Some("d1"); //~ WARN value assigned to `d` is never read
|
||||||
d = Some("d2");
|
d = Some("d2");
|
||||||
};
|
};
|
||||||
move || {
|
let _ = move || {
|
||||||
e = Some("e1"); //~ WARN value assigned to `e` is never read
|
e = Some("e1"); //~ WARN value assigned to `e` is never read
|
||||||
//~| WARN unused variable: `e`
|
//~| WARN unused variable: `e`
|
||||||
e = Some("e2"); //~ WARN value assigned to `e` is never read
|
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) {
|
pub fn g<T: Default>(mut v: T) {
|
||||||
|r| {
|
let _ = |r| {
|
||||||
if r {
|
if r {
|
||||||
v = T::default(); //~ WARN value assigned to `v` is never read
|
v = T::default(); //~ WARN value assigned to `v` is never read
|
||||||
} else {
|
} else {
|
||||||
@ -92,7 +92,7 @@ pub fn g<T: Default>(mut v: T) {
|
|||||||
|
|
||||||
pub fn h<T: Copy + Default + std::fmt::Debug>() {
|
pub fn h<T: Copy + Default + std::fmt::Debug>() {
|
||||||
let mut z = T::default();
|
let mut z = T::default();
|
||||||
move |b| {
|
let _ = move |b| {
|
||||||
loop {
|
loop {
|
||||||
if b {
|
if b {
|
||||||
z = T::default(); //~ WARN value assigned to `z` is never read
|
z = T::default(); //~ WARN value assigned to `z` is never read
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
pub fn mutable_upvar() {
|
pub fn mutable_upvar() {
|
||||||
let x = &mut 0;
|
let x = &mut 0;
|
||||||
//~^ ERROR
|
//~^ ERROR
|
||||||
move || {
|
let _ = move || {
|
||||||
*x = 1;
|
*x = 1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
pub fn mutable_upvar() {
|
pub fn mutable_upvar() {
|
||||||
let mut x = &mut 0;
|
let mut x = &mut 0;
|
||||||
//~^ ERROR
|
//~^ ERROR
|
||||||
move || {
|
let _ = move || {
|
||||||
*x = 1;
|
*x = 1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ fn drop(&mut self) {}
|
|||||||
|
|
||||||
fn reborrow_from_generator(r: &mut ()) {
|
fn reborrow_from_generator(r: &mut ()) {
|
||||||
let d = WithDrop;
|
let d = WithDrop;
|
||||||
move || { d; yield; &mut *r };
|
move || { d; yield; &mut *r }; //~ WARN unused generator that must be used
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
11
src/test/ui/nll/issue-48623-generator.stderr
Normal file
11
src/test/ui/nll/issue-48623-generator.stderr
Normal file
@ -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
|
||||||
|
|
@ -7,9 +7,9 @@
|
|||||||
|
|
||||||
mod a {
|
mod a {
|
||||||
fn b() {
|
fn b() {
|
||||||
|| {
|
(|| {
|
||||||
#[main]
|
#[main]
|
||||||
fn c() { panic!(); }
|
fn c() { panic!(); }
|
||||||
};
|
})();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// pretty-expanded FIXME #23616
|
// pretty-expanded FIXME #23616
|
||||||
|
|
||||||
#![deny(unused_mut)]
|
#![deny(unused_mut)]
|
||||||
|
#![allow(unused_must_use)]
|
||||||
|
|
||||||
// Test that mutating a mutable upvar in a capture-by-value unboxed
|
// Test that mutating a mutable upvar in a capture-by-value unboxed
|
||||||
// closure does not ice (issue #18238) and marks the upvar as used
|
// closure does not ice (issue #18238) and marks the upvar as used
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
warning: unused variable: `x`
|
warning: unused variable: `x`
|
||||||
--> $DIR/unboxed-closures-move-mutable.rs:16:17
|
--> $DIR/unboxed-closures-move-mutable.rs:17:17
|
||||||
|
|
|
|
||||||
LL | move || x += 1;
|
LL | move || x += 1;
|
||||||
| ^
|
| ^
|
||||||
@ -8,7 +8,7 @@ LL | move || x += 1;
|
|||||||
= help: did you mean to capture by reference instead?
|
= help: did you mean to capture by reference instead?
|
||||||
|
|
||||||
warning: unused variable: `x`
|
warning: unused variable: `x`
|
||||||
--> $DIR/unboxed-closures-move-mutable.rs:20:17
|
--> $DIR/unboxed-closures-move-mutable.rs:21:17
|
||||||
|
|
|
|
||||||
LL | move || x += 1;
|
LL | move || x += 1;
|
||||||
| ^
|
| ^
|
||||||
|
40
src/test/ui/unused/unused-closure.rs
Normal file
40
src/test/ui/unused/unused-closure.rs
Normal file
@ -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();
|
||||||
|
}
|
75
src/test/ui/unused/unused-closure.stderr
Normal file
75
src/test/ui/unused/unused-closure.stderr
Normal file
@ -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
|
||||||
|
|
@ -5,5 +5,5 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
let x = 1;
|
let x = 1;
|
||||||
//~^ ERROR: variable does not need to be mutable
|
//~^ ERROR: variable does not need to be mutable
|
||||||
move|| { println!("{}", x); };
|
(move|| { println!("{}", x); })();
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,5 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
let mut x = 1;
|
let mut x = 1;
|
||||||
//~^ ERROR: variable does not need to be mutable
|
//~^ ERROR: variable does not need to be mutable
|
||||||
move|| { println!("{}", x); };
|
(move|| { println!("{}", x); })();
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![allow(unreachable_code)]
|
#![allow(unreachable_code)]
|
||||||
#![allow(unused_braces, unused_parens)]
|
#![allow(unused_braces, unused_must_use, unused_parens)]
|
||||||
|
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user