# Pre-RFC: \`#\[must\_use\]\` on a Result's Ok type

**URL:** https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884
**Category:** Uncategorized
**Created:** [July 5, 2018, 5:49am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884 "2018-07-05T05:49:13Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)
#### Post date: [July 5, 2018, 5:49am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/1 "2018-07-05T05:49:13Z")

</div>

Rust 1.27 added the ability to annotate a function as `#[must_use]`, which results in a lint if you don’t use the return value. However, if a function returns `Result<T, E>`, the existing `#[must_use]` annotation on `Result` itself will only force the caller to look at the `Result` somehow, which `?` will do; that doesn’t stop the caller from then ignoring the `T`. I’d like to propose an extension to this syntax that ensures the Ok type gets used:

```rust
fn f() -> Result<#[must_use] T, E> { ... }

f(); // lint warning, must use the Result
f()?; // Also a lint warning, must use the T

```

Does this seem reasonable?

Does this syntax seem reasonable, or would some other syntax make more sense? (Note that this uses the “attributes on generic type parameters” syntax also introduced in Rust 1.27.)

---

<div class="post-metadata">

### Author: ![gbutler](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gbutler/32/3670_2.png) [@gbutler](https://internals.rust-lang.org/u/gbutler)
#### Post date: [July 5, 2018, 5:55am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/2 "2018-07-05T05:55:56Z")

</div>

What about `Option<T>`? What about `Result<Option<T>,E>`? What about `Option<Result<T,E>>` (weird)? What about `MyResultLikeStruct<T,U,E>`???

It would seem odd to special-case `Result<T,E>` and not have these and similar cases also be must\_use. What might that look like? How difficult would that be? Would it be possible?

If you couldn’t make them all work, I’d feel the justification for Result\<T,E\> would be a little weak.

---

<div class="post-metadata">

### Author: ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)
#### Post date: [July 5, 2018, 5:59am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/3 "2018-07-05T05:59:27Z")

</div>

This isn’t special-casing `Result<T, E>`; there’s no fundamental reason the syntax wouldn’t allow putting `#[must_use]` on an arbitrary type parameter. The main reason I bring it up for `Result` specifically is precisely because it’s common to write `func()?` and that would use the `Result` but not the `T`.

---

<div class="post-metadata">

### Author: ![gbutler](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gbutler/32/3670_2.png) [@gbutler](https://internals.rust-lang.org/u/gbutler)
#### Post date: [July 5, 2018, 6:02am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/4 "2018-07-05T06:02:37Z")

</div>

How does the compiler know how to use the T? It has so have special knowledge to know that it must be called as unwrap or match Some(T), no? How would that translate to other things that are similar like the straw-man I gave of, `MyResultLike< #[must_use]T,U,E>`

---

<div class="post-metadata">

### Author: ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)
#### Post date: [July 5, 2018, 6:05am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/5 "2018-07-05T06:05:33Z")

</div>

Obviously there’s a limit to how far the compiler can track this. I’m not necessarily expecting full dataflow analysis here. Just as you can write `let _ = func()` and that’s (by design) enough to silence a `#[must_use]` on `func`, I’m primarily looking to catch `func()?;`, and for that matter `func().unwrap();` or `func().unwrap_or(...);`. I can live with best-effort here; the goal is to catch a common erroneous pattern.

---

<div class="post-metadata">

### Author: ![gbutler](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gbutler/32/3670_2.png) [@gbutler](https://internals.rust-lang.org/u/gbutler)
#### Post date: [July 5, 2018, 6:07am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/6 "2018-07-05T06:07:51Z")

</div>

Would a `[#must_use]` applied T mean that any enum variant in the returned enum that encapsulates a T must be matched against? I’m having difficulty tracking this through. Probably need to go to bed.

---

<div class="post-metadata">

### Author: ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)
#### Post date: [July 5, 2018, 6:08am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/7 "2018-07-05T06:08:35Z")

</div>

A related issue I just opened today:

> <https://github.com/rust-lang/rust/issues/52062>

I’m a bit afraid of trying to expand things with `must_use` without a better model of what it’s supposed to actually do. For example, today

```rust
    4.clone(); // Warns
    (4.clone(),); // No warning

```

As to the specific solution proposal, I’m unsure what things are supposed to be affected by it. For example, does it make `.ok()` give you an `Option<#[must_use] T>`?

---

<div class="post-metadata">

### Author: ![birkenfeld](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/birkenfeld/32/1150_2.png) [@birkenfeld](https://internals.rust-lang.org/u/birkenfeld)
#### Post date: [July 5, 2018, 6:49am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/8 "2018-07-05T06:49:54Z")

</div>

Surely at some point it becomes only the caller’s choice if a return value is used or not? I understand special-casing `Result`, to encourage error handling, but this goes a lot further in the direction of “pure functions” and the associated minefield…

---

<div class="post-metadata">

### Author: ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)
#### Post date: [July 5, 2018, 7:18am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/9 "2018-07-05T07:18:45Z")

</div>

Right now, `#[must_use]` on a function can be suppressed by writing something like `let _ = func()`. You could suppress this with any number of patterns, too. This isn’t intended to flag explicitly ignoring a return value, it’s intended to flag _accidentally_ ignoring a return value.

And I’d only expect to see this attribute used on functions where it makes _no_ sense to ignore the result. For instance, if you have a “modify and return modified copy” function, that doesn’t modify in place, then it makes no sense to ignore the result; you might as well not call the function at all.

---

<div class="post-metadata">

### Author: ![Ixrec](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ixrec/32/6754_2.png) [@Ixrec](https://internals.rust-lang.org/u/Ixrec)
#### Post date: [July 5, 2018, 8:08am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/10 "2018-07-05T08:08:51Z")

</div>

Do we have any way of excluding `Result<(), Error>` from this?

---

<div class="post-metadata">

### Author: ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)
#### Post date: [July 5, 2018, 8:28am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/11 "2018-07-05T08:28:21Z")

</div>

This is for annotating a specific function’s return value. If you have a function returning `Result<(), Error>`, don’t annotate the `()` with `#[must_use]`.

If you’re concerned about a generic function being run with a type parameter of `()`, note that `#[must_use]` already handles that case as you might expect: a function returning `()` (including via generic parameter) will always consider the `()` “used” even if you don’t do anything with it, and you’ll never get an `unused_must_use` lint about it.

---

<div class="post-metadata">

### Author: ![Riateche](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/riateche/32/1717_2.png) [@Riateche](https://internals.rust-lang.org/u/Riateche)
#### Post date: [July 17, 2018, 11:27am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/12 "2018-07-17T11:27:04Z")

</div>

Looks like there are only a few cases where `must_use` on a generic type parameter would make sense. For example, what `fn f() -> Vec<#[must_use] T>` would mean?

If your primary concern is the `f()?;` case, it makes sense to only handle functions that return types that implement `Carrier`. I think it should be possible to make it work like this:

```
#[must_use_ok]
fn f() -> Result<T, E> { ... }

```

Then the compiler will issue a warning to both `f();` and `f()?;`. It doesn’t have to care what the exact structure of the return type is. If `f()`'s return type does not implement `Carrier`, adding `#[must_use_ok]` to it will result in an error. (The `must_use_ok` name is not great, though.)

There is also the `f().unwrap();` case that isn’t backed by a trait. While it’s possible to add special handling for `Result` and `Option` here, it’s hard to imagine a way to handle this for any custom type. Imagine a type like this:

```
enum MyResult<T> {
    Ok(T),
    Err,
}
struct MyAccessWrapper<T>(T);
impl<T> MyResult<T> {
    fn my_unwrap(self) -> MyAccessWrapper<T> {
        match self {
            MyResult::Ok(v) => MyAccessWrapper(v),
            MyResult::Err => panic!("err")
        }
    }
}

```

Even if you declare your function to return `MyResult<#[must_use] T>`, the compiler doesn’t have a way to handle the `f().my_unwrap();` case. The name of the unwrap function isn’t `unwrap` and its return type is not `T`, so it’s not clear in general that the return value of `my_unwrap()` must be used in this case.

---

<div class="post-metadata">

### Author: ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)
#### Post date: [July 17, 2018, 7:10pm UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/13 "2018-07-17T19:10:00Z")

</div>

This seems plausible to me. It doesn’t special-case Result specifically, and it should work for any implementation of `Try` (or whatever we end up calling it when stabilized).

---

<div class="post-metadata">

### Author: ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)
#### Post date: [March 25, 2019, 8:30am UTC](https://internals.rust-lang.org/t/pre-rfc-must-use-on-a-results-ok-type/7884/14 "2019-03-25T08:30:28Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
