Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions compiler/rustc_lint/src/unused/must_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,6 @@ impl IsTyMustUse {
_ => self,
}
}

fn yes(self) -> Option<MustUsePath> {
match self {
Self::Yes(must_use_path) => Some(must_use_path),
_ => None,
}
}
}

/// A path through a type to a `must_use` source. Contains useful info for the lint.
Expand Down Expand Up @@ -254,16 +247,23 @@ pub fn is_ty_must_use<'tcx>(
// Default to `expr`.
let elem_exprs = elem_exprs.iter().chain(iter::repeat(expr));

let nested_must_use = tys
.iter()
.zip(elem_exprs)
.enumerate()
.filter_map(|(i, (ty, expr))| {
is_ty_must_use(cx, ty, expr, simplify_uninhabited).yes().map(|path| (i, path))
})
.collect::<Vec<_>>();
let mut all_trivial = true;
let mut nested_must_use = Vec::new();

tys.iter().zip(elem_exprs).enumerate().for_each(|(i, (ty, expr))| {
let must_use = is_ty_must_use(cx, ty, expr, simplify_uninhabited);

all_trivial &= matches!(must_use, IsTyMustUse::Trivial);
if let IsTyMustUse::Yes(path) = must_use {
nested_must_use.push((i, path));
}
});

if !nested_must_use.is_empty() {
if all_trivial {
// If all tuple elements are trivial, mark the whole tuple as such.
// i.e. don't emit `unused_results` for types such as `((), ())`
IsTyMustUse::Trivial
} else if !nested_must_use.is_empty() {
IsTyMustUse::Yes(MustUsePath::TupleElement(nested_must_use))
} else {
IsTyMustUse::No
Expand Down
15 changes: 15 additions & 0 deletions tests/ui/lint/unused/unused-result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
//~^ NOTE: the lint level is defined here
//~| NOTE: the lint level is defined here

use std::ops::ControlFlow;

#[must_use]
enum MustUse { Test }

#[must_use = "some message"]
enum MustUseMsg { Test2 }

enum Nothing {}

fn foo<T>() -> T { panic!() }

fn bar() -> isize { return foo::<isize>(); }
Expand Down Expand Up @@ -39,4 +43,15 @@ fn main() {
let _ = foo::<isize>();
let _ = foo::<MustUse>();
let _ = foo::<MustUseMsg>();

// "trivial" types
();
((), ());
Ok::<(), Nothing>(());
ControlFlow::<Nothing>::Continue(());
((), Ok::<(), Nothing>(()), ((((), ())), ((),)));
foo::<Nothing>();

((), 1); //~ ERROR: unused result of type `((), i32)`
(1, ()); //~ ERROR: unused result of type `(i32, ())`
}
24 changes: 18 additions & 6 deletions tests/ui/lint/unused/unused-result.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: unused `MustUse` that must be used
--> $DIR/unused-result.rs:21:5
--> $DIR/unused-result.rs:25:5
|
LL | foo::<MustUse>();
| ^^^^^^^^^^^^^^^^
Expand All @@ -15,7 +15,7 @@ LL | let _ = foo::<MustUse>();
| +++++++

error: unused `MustUseMsg` that must be used
--> $DIR/unused-result.rs:22:5
--> $DIR/unused-result.rs:26:5
|
LL | foo::<MustUseMsg>();
| ^^^^^^^^^^^^^^^^^^^
Expand All @@ -27,7 +27,7 @@ LL | let _ = foo::<MustUseMsg>();
| +++++++

error: unused result of type `isize`
--> $DIR/unused-result.rs:34:5
--> $DIR/unused-result.rs:38:5
|
LL | foo::<isize>();
| ^^^^^^^^^^^^^^^
Expand All @@ -39,7 +39,7 @@ LL | #![deny(unused_results, unused_must_use)]
| ^^^^^^^^^^^^^^

error: unused `MustUse` that must be used
--> $DIR/unused-result.rs:35:5
--> $DIR/unused-result.rs:39:5
|
LL | foo::<MustUse>();
| ^^^^^^^^^^^^^^^^
Expand All @@ -50,7 +50,7 @@ LL | let _ = foo::<MustUse>();
| +++++++

error: unused `MustUseMsg` that must be used
--> $DIR/unused-result.rs:36:5
--> $DIR/unused-result.rs:40:5
|
LL | foo::<MustUseMsg>();
| ^^^^^^^^^^^^^^^^^^^
Expand All @@ -61,5 +61,17 @@ help: use `let _ = ...` to ignore the resulting value
LL | let _ = foo::<MustUseMsg>();
| +++++++

error: aborting due to 5 previous errors
error: unused result of type `((), i32)`
--> $DIR/unused-result.rs:55:5
|
LL | ((), 1);
| ^^^^^^^^

error: unused result of type `(i32, ())`
--> $DIR/unused-result.rs:56:5
|
LL | (1, ());
| ^^^^^^^^

error: aborting due to 7 previous errors

Loading