Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

the advice for unused return value of std::option::Option::<T>::map_or is wrong #11282

Open
shionryuu opened this issue Aug 2, 2023 · 2 comments
Labels
C-bug Category: Clippy is not doing the correct thing

Comments

@shionryuu
Copy link

Summary

before:

error: unused return value of `std::option::Option::<T>::map_or` that must be used
   --> src/xxx.rs:119:9
    |
119 | /         self.m.get_mut(&key).map_or((), |series| {
120 | |             if let Some(last_elem) = series.last() {
121 | |                 if last_elem.timestamp == timestamp {
122 | |                     series.pop();
...   |
125 | |             series.push(Value { value, timestamp });
126 | |         });
    | |__________^
    |
    = note: if you don't need the returned value, use `if let` instead
    = note: `-D unused-must-use` implied by `-D warnings`
help: use `let _ = ...` to ignore the resulting value
    |
119 |         let _ = self.m.get_mut(&key).map_or((), |series| {
    |         +++++++

after:

error: this let-binding has unit value
   --> src/xxx.rs:119:9
    |
119 | /         let _ = self.m.get_mut(&key).map_or((), |series| {
120 | |             if let Some(last_elem) = series.last() {
121 | |                 if last_elem.timestamp == timestamp {
122 | |                     series.pop();
...   |
125 | |             series.push(Value { value, timestamp });
126 | |         });
    | |___________^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_unit_value
    = note: `-D clippy::let-unit-value` implied by `-D warnings`
help: omit the `let` binding
    |
119 ~         self.m.get_mut(&key).map_or((), |series| {
120 +             if let Some(last_elem) = series.last() {
121 +                 if last_elem.timestamp == timestamp {
122 +                     series.pop();
123 +                 }
124 +             }
125 +             series.push(Value { value, timestamp });
126 +         });

Reproducer

I tried this code:

pub struct TimeMap2 {
    m: HashMap<String, Vec<Value>>,
}

impl TimeMap2 {
    pub fn new() -> Self {
        Self { m: HashMap::new() }
    }

    pub fn set(&mut self, key: String, value: String, timestamp: i32) {
        if !self.m.contains_key(&key) {
            self.m.insert(key.clone(), Vec::new());
        }

        self.m.get_mut(&key).map_or((), |series| {
            if let Some(last_elem) = series.last() {
                if last_elem.timestamp == timestamp {
                    series.pop();
                }
            }
            series.push(Value { value, timestamp });
        });
    }

    pub fn get(&self, key: String, timestamp: i32) -> String {
        if let Some(series) = self.m.get(&key) {
            if series.is_empty() {
                return String::new();
            }
            return match series.binary_search_by_key(&timestamp, |v| v.timestamp) {
                Ok(idx) => series[idx].value.clone(),
                Err(idx) => {
                    if let Some(val) = series.get(idx - 1) {
                        return val.value.clone();
                    }
                    String::new()
                }
            };
        }
        String::new()
    }
}

I expected to see this happen:

Instead, this happened:

Version

rustc 1.71.0 (8ede3aae2 2023-07-12)
binary: rustc
commit-hash: 8ede3aae28fe6e4d52b38157d7bfe0d3bceef225
commit-date: 2023-07-12
host: x86_64-unknown-linux-gnu
release: 1.71.0
LLVM version: 16.0.5

Additional Labels

No response

@shionryuu shionryuu added the C-bug Category: Clippy is not doing the correct thing label Aug 2, 2023
@y21
Copy link
Member

y21 commented Aug 2, 2023

Hmm, looks like clippy and rustc don't agree with each other when calling a function marked #[must_use]. Clippy should probably check if the binding initializer is a function call and make sure it doesn't have that attribute.
It's kind of weird to have a #[must_use] function return (), but I guess it can happen in generic contexts like here.

@Centri3
Copy link
Member

Centri3 commented Aug 2, 2023

For now, as a workaround, you can wrap it in a 1-len slice, like
let [()] = [<call>]
(Or, of course, allowing the lint ^^)

Once #10844 is merged, you can write let () = <call> instead. I believe unused_must_use won't lint there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing
Projects
None yet
Development

No branches or pull requests

3 participants