Adding Option.expect_none

There exists Option.expect, Result.expect, Result.expect_err, but not Option.expect_none.

I understand that the three methods above are used for unwrapping the underlying value, but for functions that return (), unwrapping is a convenient way to panic upon unexpected returns.

Right now, to panic if a function doesn’t return None, I have to wrap it with assert!(expr_that_returns_option.is_none(), "Error message").

It would be much more readable, convenient and motivating to add sanity checks if an expect_none() is introduced.

3 Likes

Personally I’d prefer just using a Result<(), ()>.

My particular use case was where the Option came from a library. I could have used ok_or(), but that’s super ugly.

So the main advantage of expect_none() (vs. assert) would be that you could easily add it to the end of a method chain. That’s a similar reason to why postfix .await was chosen though, so you may find the libs team receptive to this.

1 Like

True, but .await results in a useful value (so further chaining is possible). But expect_none() on an Option just results in (), so it lacks much of the chaining benefit that .await has.

I think it’s fine that this wouldn’t enable further chaining – it still lets you avoid wrapping the expression.

I would like this, I find it to be more clear than the assert and the parallel to Result makes it desirable. I have reached for something like expect_none more than a few times, and it would be nice to see it added.

6 Likes

I’d love this! I often want to assert, after inserting into a HashMap, that this key was not used before. There currently is no nice way to do this. With this change, I could do

map.insert(key, value).expect_none();
12 Likes

Convention would require unwrap_none(self) -> () and expect_none(self, msg: &str) -> ().

3 Likes

Of if we had macros in tail position, i.e. where macro!(foo) is same as foo.macro!(), then you could do:

map.insert(key, value).is_none().assert!();
1 Like

I don’t know, it seems to be pretty small motivation to bloat the library with this particular method. I mean, you can come up with infinite number of methods you’d find handy from time to time, even though they can be easily combined from smaller parts. We can’t just put infinite number of methods in :innocent:.

But we have a very similar method on Result, so there is some precedent to adding expect_none(...). This isn’t coming from nowhere. Also this would be a tiny addition that would be very helful when writing tests or expressing invariants, so I see it as a net win.

This would also be nice to have for warnings – unwrap_none is exactly what https://github.com/rust-lang/rust/pull/62431#discussion_r302180901 wants to be able to mention in a must_use warning for is_none, for consistency with the warnings on is_some, is_ok, & is_err.

1 Like
4 Likes