timlyo
timlyo

Reputation: 2384

Can I apply must_use to a function result?

I have a function that returns a f64. I'd like to ensure that the output from this function is used, rather than just ignored. Is there any way to do this?

The return type is not used for error handling so wrapping it in a Result or Option doesn't really make sense.

I'd like something similar to this:

#[must_use]
fn calculate_the_thing(number: f64) -> f64 {
    number * 2.0
}

Upvotes: 11

Views: 4893

Answers (2)

huon
huon

Reputation: 102096

Since Rust 1.27 #[must_use] attribute can be used on functions

#[must_use]
fn calculate_the_thing(number: f64) -> f64 {
    number * 2.0
}

fn main() {
    calculate_the_thing(4); // warning: unused return value of `calculate_the_thing ` which must be used

    let _ = calculate_the_thing(4); // (no warning)
}

In older versions, #[must_use] only applied to types, not individual values.

One alternative is to define a simple wrapper type that is #[must_use]:

#[must_use = "this value should be used (extract with .0)"]
pub struct MustUse<T>(pub T);

Your function can then return MustUse<f64>, and users will get a warning if they write calculate_the_thing(12.3), even suggesting the right way to get the thing they want: let x = calculate_the_thing(12.3).0;. For instance:

fn calculate_the_thing(number: f64) -> MustUse<f64> {
    MustUse(number * 2.0)
}

fn main() {
    calculate_the_thing(12.3); // whoops
    
    let x = calculate_the_thing(12.3).0;
    println!("{}", x);
}
warning: unused `MustUse` which must be used: this value should be used (extract with .0)
 --> src/main.rs:9:5
  |
9 |     calculate_the_thing(12.3); // whoops
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: #[warn(unused_must_use)] on by default

Upvotes: 20

Shepmaster
Shepmaster

Reputation: 430851

Yes, you can, thanks to RFC 1940 and available starting in Rust 1.27. Your original code works as-is:

#[must_use]
fn calculate_the_thing(number: f64) -> f64 {
    number * 2.0
}

fn main() {
    calculate_the_thing(21.0);
}
warning: unused return value of `calculate_the_thing` which must be used
 --> src/main.rs:7:5
  |
7 |     calculate_the_thing(21.0);
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: #[warn(unused_must_use)] on by default

    Finished dev [unoptimized + debuginfo] target(s) in 0.71s
     Running `target/debug/playground`

Upvotes: 12

Related Questions