-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Tracking issue for Option::expect_none(msg) and unwrap_none() #62633
Comments
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I guess it could use more in-repo callers? I do see that |
I'd love to see this go to stable.. I'm having to do this: let old_value = self.values.insert(key, value);
assert!(old_value.is_none()); And I'd much rather do self.values.insert(key, value).unwrap_none(); |
In the stabilization PR it was raised that |
You can use |
I'd like to see |
cc rust-lang#62633 These methods have been on nightly for over a year without any issues.
@aclysma what would |
EDIT: Oops! I didn't realize I already had this example above: #62633 (comment) (More examples here: https://github.com/aclysma/rafx/search?q=old.is_none) |
It could be called |
My two cents on this topic after finding myself wanting to use these APIs: Besides #73077 (comment), I do believe there is value to add As for the name of the methods, I believe That said, I would either stick with |
I'd argue for expect_none and unwrap_none as standard. Having them as optional "features" is a strange limbo state. That creates confusion as to whether they're staying around or going away. Using "assert!" around an expression which must be executed for its side effects seems poor form. My main use case for this is for collection "insert" operations where failure is not expected and should be fatal. It's tempting to write let _ = somehash.insert(k,v); but it's better to check. A concise syntax for checking is a good thing in this situation. |
@rfcbot fcp close We discussed this in the Libs meeting and decided against stabilizing these methods in favor of The reasoning was that all this method can do is either succeed with a |
Team member @KodrAus has proposed to close this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
…chenkov Remove unwrap_none/expect_none from compiler/. We're not going to stabilize `Option::{unwrap_none, expect_none}`. (See rust-lang#62633.) This removes the usage of those unstable methods from `compiler/`.
…chenkov Remove unwrap_none/expect_none from compiler/. We're not going to stabilize `Option::{unwrap_none, expect_none}`. (See rust-lang#62633.) This removes the usage of those unstable methods from `compiler/`.
…chenkov Remove unwrap_none/expect_none from compiler/. We're not going to stabilize `Option::{unwrap_none, expect_none}`. (See rust-lang#62633.) This removes the usage of those unstable methods from `compiler/`.
…chenkov Remove unwrap_none/expect_none from compiler/. We're not going to stabilize `Option::{unwrap_none, expect_none}`. (See rust-lang#62633.) This removes the usage of those unstable methods from `compiler/`.
…chenkov Remove unwrap_none/expect_none from compiler/. We're not going to stabilize `Option::{unwrap_none, expect_none}`. (See rust-lang#62633.) This removes the usage of those unstable methods from `compiler/`.
Remove Option::{unwrap_none, expect_none}. This removes `Option::unwrap_none` and `Option::expect_none` since we're not going to stabilize them, see rust-lang#62633. Closes rust-lang#62633
I hope it is fine that im writing here. I just stumbled over this api and was wondering about the |
@Bendrien |
My god, what is the harm in adding People here seem to completely miss the idea behind using it. It is obviously not about unwrapping to get some value, but about panicking when it is not none. maybe "unwrap_none" sounds a bit odd, but "expect_none" is very clear. Also "unwrap_none" makes sense when the wrapper is empty. Having to wrap an Option in an |
This makes me once again wish that And yeah, I have run into the same iterator usecase as @hikari-no-yume and used to use |
Sorry, I deleted the comment you're referencing (where I mentioned it would be nice to be able to do I saw the wisdom of the lib team's argument when I noticed I'd also then want |
which obviously uses way more characters than |
I’m still doing this, over and over.
The libs team implemented an alternative in response to it #82764 18 months later, it hasn’t moved. So I’m stuck here doing this over and over. (Additionally, I’m still disappointed at how this FCP was handled. Not just the result, but the way in which the libs team executed the process/engaged with the community) |
The problem is that this issue is fundamentally an XY problem, where the real problem is the lack of postfix macros but we tried to solve this problem by bloating the standard library instead. |
I disagree with that, unless you think 'unwrap' and 'expect' are also just bloat and should have been postfix macros (but then I don't know which macro).
But I think I will use "x.ok_or(()).expect_err(...)" for now for the iterator case (where one wants to check that the last next() returns None), that is at least almost symmetric with the earlier calls to next that should return Some.
|
@RalfJung yes, I think value.expect!()
value.expect!("expect message")
value.expect!("formatted {expect} {}", message) |
Add {BTreeMap,HashMap}::try_insert `{BTreeMap,HashMap}::insert(key, new_val)` returns `Some(old_val)` if the key was already in the map. It's often useful to assert no duplicate values are inserted. We experimented with `map.insert(key, val).unwrap_none()` (rust-lang/rust#62633), but decided that that's not the kind of method we'd like to have on `Option`s. `insert` always succeeds because it replaces the old value if it exists. One could argue that `insert()` is never the right method for panicking on duplicates, since already handles that case by replacing the value, only allowing you to panic after that already happened. This PR adds a `try_insert` method that instead returns a `Result::Err` when the key already exists. This error contains both the `OccupiedEntry` and the value that was supposed to be inserted. This means that unwrapping that result gives more context: ```rust map.insert(10, "world").unwrap_none(); // thread 'main' panicked at 'called `Option::unwrap_none()` on a `Some` value: "hello"', src/main.rs:8:29 ``` ```rust map.try_insert(10, "world").unwrap(); // thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: // OccupiedError { key: 10, old_value: "hello", new_value: "world" }', src/main.rs:6:33 ``` It also allows handling the failure in any other way, as you have full access to the `OccupiedEntry` and the value. `try_insert` returns a reference to the value in case of success, making it an alternative to `.entry(key).or_insert(value)`. r? ```@Amanieu``` Fixes rust-lang/rfcs#3092
This statement doesn't really make any sense. You aren't unwrapping the
I'm skeptical of this at its face value. The notion of
This is simply not ergonomically consistent with how one expects to assert the valuedness of the container enums. Unless there are plans to deprecate the panicking
This seems like skirting around the reality that the expectation of a semantic way to inline-assert the valuedness of a container has already been proposed in this issue. You certainly can introduce the function discussed in this thread as an entirely new unwrapping API separate from the existing unwrapping APIs, but it feels like arbitrarily beating around the bush of this issue. Really, this is functionally another inline syntax for Overall, reading this, I wasn't particularly satisfied with the responses, justifications, or in general the way this issue was handled. There was next to no communication while the issue was being reviewed, followed by subjective arguments, followed (finally) by an actual discussion of the logical reasoning of the libs team. It really just seems like the team that voted on this doesn't like the idea of unwrapping an empty 🎁. |
Quoting @SOF3
Which would be fine, except that 5 years on we don't have a solution for X OR Y. And none of the alternatives mentioned to solve this have moved even slightly over 5 years. And, if postfix macros didn't get resolved given their usefulness for "async" which everybody on the core team was totally obsessed with, they are never going to move. So, I'm so glad you maintained your vaunted "language purity", but, in the meantime, users of the language are still stuck exactly where they started. That's fine. Many of us can take a hint and understand that it is time to move on from Rust. |
To contrast, I find there is value in a clean code base and principled design. But I think pragmatism is one of the most important principles which should drive language design. And I personally don't really have any validated reasons on my list about why |
Sure.
To unwrap the
So then the question is whether we want such methods. I don't think we do, because we also don't have anything like
I don't think Rust is very "pure". I also don't think users are "stuck". There are many simple ways to express a check for
Many reasons have been given in this thread. I'm not sure what I can add at this point without just repeating things that have already been said. |
As I highlighted here, we're all just volunteers working on the standard library next to many other tasks, so while we'll try our best to communicate everything as clearly as possible, it sometimes takes longer than you might hope for.
I'm afraid that API design will always be based on subjective arguments. There's no objective right or wrong way to design a library.
I'm not sure what you expect from us at this point. Many arguments have been given and thoroughly explained over the past few years, and it just seems like we're going in circles now. :/ |
The unexpected. I mean, literally, the |
There was no way to assert that an option value is None, so I add is_none which returns true if the value is None. Rust seems to have decided against unwrap_none, so I will not go down that path. rust-lang/rust#62633 assert!(is_none(x)) might produce slightly larger Simplicity expressions than a hypothetical unwrap_none(x), but I will not try to prematurely optimize any Simplicity code here. A future version of the Simfony compiler might detect assert! + is_none and produce an optimized Simplicity expression accordingly.
There was no way to assert that an option value is None, so I add is_none which returns true if the value is None. Rust seems to have decided against unwrap_none, so I will not go down that path. rust-lang/rust#62633 assert!(is_none(x)) might produce slightly larger Simplicity expressions than a hypothetical unwrap_none(x), but I will not try to prematurely optimize any Simplicity code here. A future version of the Simfony compiler might detect assert! + is_none and produce an optimized Simplicity expression accordingly.
There was no way to assert that an option value is None, so I add is_none which returns true if the value is None. Rust seems to have decided against unwrap_none, so I will not go down that path. rust-lang/rust#62633 assert!(is_none(x)) might produce slightly larger Simplicity expressions than a hypothetical unwrap_none(x), but I will not try to prematurely optimize any Simplicity code here. A future version of the Simfony compiler might detect assert! + is_none and produce an optimized Simplicity expression accordingly.
Steps:
must_use
message onis_none
(per Add messages toOption
's andResult
'smust_use
annotation foris_*
#62431 (review))The text was updated successfully, but these errors were encountered: