# Provocative question: should you have to use \`Result\<T, !\>\`

**URL:** <https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403>\
**Category:** Uncategorized\
**Created:** [June 15, 2019, 1:39pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403 "2019-06-15T13:39:22Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![derekdreery](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/derekdreery/32/2632_2.png) [@derekdreery](https://internals.rust-lang.org/u/derekdreery)\
**Post date:** [June 15, 2019, 1:39pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/1 "2019-06-15T13:39:23Z")

</div>

Arguments for

- More consistent
- Probably simpler in the linter

Arguments against

- Unnecessary unwrap clutter (error path will never be taken)

---

<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:** [June 15, 2019, 1:46pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/2 "2019-06-15T13:46:57Z")

</div>

What alternative are you trying to argue against? Could you give some example code? It’s not really possible to engage with this post as currently written. I can only guess that you might not be aware of these two details:

1. There’s been talk for a long time of making code like `let r: Result<T, !> = Ok(t1); let t2: T = r;` just work without an `.unwrap()` precisely because the type system can statically know that there’s no possibility of panicking there. AFAIK, this is actually part of the motivation of introducing `!` as a single standard “type with zero values”/“never type” instead of everyone writing their own distinct zero-variant enum.

2. You’re not expected to actually write things like `Result<T, !>` all that often yourself. For the most part, `!` is only expected to show up as a result of generic code that has to handle non-`!` types being called from concrete code that knows it’s dealing with a special degenerate case–like an operation that’s normally fallible but in your application happens to be completely infallible–and we really want that generic code to get some extra optimizations that are only possible in the infallible case (like not generating any panic-handling code).

---

<div class="post-metadata">

**Author:** ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)\
**Post date:** [June 15, 2019, 1:47pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/3 "2019-06-15T13:47:56Z")

</div>

Yes, if a trait interface requires `Result` and allows you to choose the error, and you know you will never take the `Err` branch. Like in `TryFrom::try_from`

---

<div class="post-metadata">

**Author:** ![phaylon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/phaylon/32/62_2.png) [@phaylon](https://internals.rust-lang.org/u/phaylon)\
**Post date:** [June 15, 2019, 1:57pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/4 "2019-06-15T13:57:18Z")

</div>

> [@Ixrec](#):
>
> There’s been talk for a long time of making code like `let r: Result<T, !> = Ok(t1); let t2: T = r;` just work without an `.unwrap()` precisely because the type system can statically know that there’s no possibility of panicking there. AFAIK, this is actually part of the motivation of introducing `!` as a single standard “type with zero values”/“never type” instead of everyone writing their own distinct zero-variant enum.

I must have missed that, would you happen to have a link? I would feel very disappointed if that would end up applying to all infallible patterns. For example, I wouldn't want

```rust
struct Score(usize);
let score = Score(100);
let account = &accounts[score];

```

to compile. It would cancel out quite a lot of newtype safety.

---

<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:** [June 15, 2019, 1:59pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/5 "2019-06-15T13:59:58Z")

</div>

Huh, I’ve never heard anyone suggest making newtypes/single-field structs coerce like that. The idea I’m talking about is (assuming I ever really understood it) making enums with all but one variant of type `!` coerce to or just be equivalent to the type of the non-`!` variant.

(afaik nothing like this has actually been _accepted_ yet, the original RFC for `!` only suggests specialized methods with names like `unwrap_nopanic`).

---

<div class="post-metadata">

**Author:** ![derekdreery](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/derekdreery/32/2632_2.png) [@derekdreery](https://internals.rust-lang.org/u/derekdreery)\
**Post date:** [June 15, 2019, 2:04pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/6 "2019-06-15T14:04:19Z")

</div>

If anyone’s interested the place I’ve seen this is using the `nb` crate for non-blocking embedded i/o.

```rust
pub enum nb::Error<E> {
    WouldBlock,
    RealError(E)
}

pub type nb::Result<T, E> = Result<T, nb::Error<E>>;

macro_rules! block {
    ($e:expr) => {
        loop {
           match $e {
                 Ok(t) => break Ok(t),
                 Err(Error::WouldBlock) => (),
                 Err(Error::Other(e)) => break Err(e)
            }
        }
    }
}

// implementation
pub fn blocking_but_never_fails() -> nb::Result<(), !> {
    writer_that_never_fails_but_sometimes_blocks.write(b'!')?;
    Ok(())
}

// usage
block!(blocking_but_never_fails()).unwrap(); // the unwrap is redundant here

```

**Disclaimer** The above code doesn’t compile and exists for demonstration only

---

<div class="post-metadata">

**Author:** ![phaylon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/phaylon/32/62_2.png) [@phaylon](https://internals.rust-lang.org/u/phaylon)\
**Post date:** [June 15, 2019, 2:06pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/7 "2019-06-15T14:06:24Z")

</div>

> [@Ixrec](#):
>
> Huh, I’ve never heard anyone suggest making newtypes/single-field structs coerce like that. The idea I’m talking about is (assuming I ever really understood it) making enums with all but one variant of type `!` coerce to the type of the non- `!` variant.

That's why I asked if you had a link 🙂 I think it might be fine if it were just happening apply to `Result<T, !>`, or if a type had to opt-in. I'm not sure I'd like it in general. An

```rust
enum Position<T, U> {
    Absolute(T),
    Relative(U),
}
type CurrentCase = Position<usize, !>;

```

shouldn't simply be usable as a `usize` because the `Relative` variant is impossible.

---

<div class="post-metadata">

**Author:** ![phaylon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/phaylon/32/62_2.png) [@phaylon](https://internals.rust-lang.org/u/phaylon)\
**Post date:** [June 15, 2019, 2:09pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/8 "2019-06-15T14:09:36Z")

</div>

Potentially related discussion: [Add methods for unwrapping Result\<T, !\> / Result\<!, E\>](https://github.com/rust-lang/rfcs/issues/1723#)

---

<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:** [June 15, 2019, 2:10pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/9 "2019-06-15T14:10:44Z")

</div>

Fastest citations I could find:

[https://github.com/rust-lang/rust/issues/35121#issuecomment-245826221](https://github.com/rust-lang/rust/issues/35121#issuecomment-245826221) and many nearby comments on making `!` affect exhaustiveness checking of `match` blocks

[https://github.com/rust-lang/rust/issues/35121#issuecomment-248720913](https://github.com/rust-lang/rust/issues/35121#issuecomment-248720913) suggests extending this to `!` affecting what patterns are irrefutable, basically what I meant in my earlier post.

[https://github.com/rust-lang/rust/issues/35121#issuecomment-360027186](https://github.com/rust-lang/rust/issues/35121#issuecomment-360027186) explicitly leaves the irrefutable patterns thing out of the first stabilization attempt, moving it to [https://github.com/rust-lang/rfcs/pull/1872](https://github.com/rust-lang/rfcs/pull/1872)

[https://github.com/rust-lang/rfcs/pull/1872#issuecomment-358795038](https://github.com/rust-lang/rfcs/pull/1872#issuecomment-358795038) closed that RFC on the grounds that it affects unsafe code in ways we don’t fully understand yet. Huh, I had no idea this was UCG-related!

Hopefully that’s enough to substantiate the “people have been talking about this” claim.

---

<div class="post-metadata">

**Author:** ![phaylon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/phaylon/32/62_2.png) [@phaylon](https://internals.rust-lang.org/u/phaylon)\
**Post date:** [June 15, 2019, 2:19pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/10 "2019-06-15T14:19:51Z")

</div>

> [@Ixrec](#):
>
> Fastest citations I could find:

I'm aware of the discussions regarding things like:

```rust
let r: Result<i32, !> = Ok(23);
let Ok(v) = r;
match r {
    Ok(v) => v,
}

```

which is a great feature, as it allows code to break at compile time when a pattern is no longer impossible, compared to the current situation of requiring a runtime panic.

What I haven't seen is the

```rust
let r: Result<i32, !> = Ok(23);
let v: i32 = r;

```

part without any kind of unwrapping, which would worry me if not very constrained.

---

<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:** [June 15, 2019, 2:27pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/11 "2019-06-15T14:27:41Z")

</div>

> [@phaylon](#):
>
> What I haven’t seen is the
> 
> ```rust
> let r: Result<i32, !> = Ok(23);
> let v: i32 = r;
> 
> ```
> 
> part without any kind of unwrapping, which would worry me if not very constrained.

All the links in my previous post except the first are explicitly about this. Perhaps I should've pulled in exact quotes:

> [@](#):
>
> [taralx](https://github.com/taralx) commented [on 21 Sep 2016](https://github.com/rust-lang/rust/issues/35121#issuecomment-248720913)
> 
> While we're at it, does it make sense to make some patterns irrefutable in the face of `!` ?
> 
> ```rust
> let res: Result<u32, !> = ...;
> let Ok(value) = res;
> 
> ```

> [@](#):
>
> [canndrew](https://github.com/canndrew) commented [on 24 Jan 2018](https://github.com/rust-lang/rust/issues/35121#issuecomment-360027186)
> 
> [@nikomatsakis](https://github.com/nikomatsakis) Something like this?
> 
> # Summary issue - stabilization of `!`
> 
> ## What is being stabilized
> 
> [snip]
> 
> ## What is _not_ being stabilized
> 
> - Exhaustive pattern-matching for uninhabited types. eg.
> 
> ```rust
> let x: Result<u32, !> = ...;
> let Ok(y) = x;
> 
> ```
> 
> [snip] See [RFC 1872](https://github.com/rust-lang/rfcs/pull/1872) for progress on this issue. [snip]

And from [that closed RFC](https://github.com/canndrew/rfcs/blob/match-exhaustiveness/text/0000-match-exhaustiveness.md):

> [@](#):
>
> Consider a method never\_fails which returns Result\<T, !\>. With the current rules, we'd have to call such a method like this:
> 
> ```rust
> let t = match never_fails() {
> Ok(t) => t,
> Err(e) => e,
> }
> 
> ```
> 
> This relies in an unintuitive way on the !-type's ability to transmogrify into other types. Alternatively we could also write it like this:
> 
> ```rust
> let t = match never_fails() {
> Ok(t) => t,
> Err(e) => match e {},
> }
> 
> ```
> 
> But it would be nicer if we could simply write this:
> 
> ```rust
> let t = match never_fails() {
> Ok(t) => t,
> }
> 
> ```
> 
> Or even this:
> 
> ```rust
> let Ok(t) = never_fails();
> 
> ```
> 
> Not only are these ways or writing the above code more concise, they don't force the user to write dead code to explicitly handle a value that can never occur. These ways of writing patterns aren't a new extra feature, they're just what you get if you naturally extend to current syntax to cover uninhabited types the same way it handles all other types. As such, they should be legal.

I can't detect any mention of "constraints" in these discussions, other than the maybe implicit one that people seem to only be suggesting it for enums.

To be super clear, I have no strong opinion on whether this is a good or bad feature. I am merely claiming that this has been an explicit part of the discussion of the `!` type for a long time (although that discussion is so vast it's very easy to miss a detail like this), which should be undoubtable after seeing these quotes.

I did make a mistake in my first post by saying `let t = r;` instead of `let Ok(t) = r;`. No one appears to have ever proposed the former, and now that I'm thinking harder about all this, the latter does make way more sense to me.

---

<div class="post-metadata">

**Author:** ![phaylon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/phaylon/32/62_2.png) [@phaylon](https://internals.rust-lang.org/u/phaylon)\
**Post date:** [June 15, 2019, 2:33pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/12 "2019-06-15T14:33:43Z")

</div>

> [@Ixrec](#):
>
> I did make a mistake in my first post by saying `let t = r;` instead of `let Ok(t) = r;` . No one appears to have ever proposed the former, and now that I’m thinking harder about all this, the latter does make way more sense to me.

Yeah, that was the only thing that surprised me 🙂 Thanks for clarifying!

---

<div class="post-metadata">

**Author:** ![derekdreery](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/derekdreery/32/2632_2.png) [@derekdreery](https://internals.rust-lang.org/u/derekdreery)\
**Post date:** [June 15, 2019, 3:31pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/13 "2019-06-15T15:31:45Z")

</div>

If you use the pattern matching solution, you still have to write

```rust
let Ok(()) = my_func()

```

---

<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:** [September 13, 2019, 3:36pm UTC](https://internals.rust-lang.org/t/provocative-question-should-you-have-to-use-result-t/10403/14 "2019-09-13T15:36:14Z")

</div>

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