-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
try! not usable in main() #12130
Comments
Closing as intended behavior. The Two other options you have are:
|
IO directly in main is common in small scripts and utilities, where you're most interested in convenience. unwrap() is probably fine for these use cases, but it's frustrating that if_ok! falls over here given that it's blessed enough to be a globally available macro, it's likely going to be common in example code, and it's not apparent from the name what it's doing under the covers. This is kind of a nebulous complaint, I know. I'm not asking for if_ok! as currently conceived to start working in main. But I think at the very least it's a ding against if_ok! being promoted widely as an alternative to verbose IO error handling, because limitations like this are going to bite people and just generally be irritating. |
If you're willing to write
That's the subject of #12037. The macro itself is quite simple, and that is an explicit goal of the macro to stay that way.
I disagree. I think that there is no one solution for error handling and you need to understand the primitives that are available to you and make the right choice based on that. The
I/O errors in general are a little irritating. Robustly handling errors is fairly uncommon and the standard library shouldn't be helping you sweep errors under the rug. You should know exactly where all errors can happen and then as a consumer of a library you decide what to do about it. The libraries give you the tools necessary to handle these errors. |
I'm not trying to help anyone "sweep errors under the rug", I'm saying that if_ok! in its current form has limitations that are annoying for a blessed global macro that's going to be frequently highlighted as the best way to make otherwise verbose IO handling tolerable (see, for instance, the final edit on this post from Reddit today). If the official position is for people to be casual about writing their own alternate macros, why provide if_ok! at all? |
This is where I think our understanding of this macro diverges. The The The |
It's frustrating that you're putting words in my mouth. I don't want to sweep errors under the rug and I'm not thinking of What benefit does the user get from I've heard two candidate benefits in this thread:
I don't know what the answer is. Maybe it's revisiting |
I'm sorry if I sounded like I was putting words in your mouth, I definitely didn't want to do that. I was just trying to interpret what you're thinking is. I think something that would be helpful to me is a suggestion of a solution to this problem. Do you have on in mind already? |
Thank you, and apologies if I came across as overly defensive. I do feel bad raising the concern when I don't have a great answer in mind, but a few thoughts are:
|
Can a procedural macro look at the context in which it's invoked such that When the return type of expansion context is not I'm not sure if either of the two above are possible. That is looking at context of expansion, and adding warning spans, from within a procedural macro. |
How about unwrap! ?
|
What would a macro do that the method doesn't? let a = something.unwrap(); |
It's not exactly clear to me what In the code
For the non-error case the line When i change the example code to return an error, what is supposed to happen? The if_ok!() will then return some Err()... Am i to handle that case with some match statement anyway? It's back to I have not much experience with Rust so i suppose i am missing something, but my thought probably gives some insight from a rust beginner/python convert what may be confusing for other people as well... |
@buster struct Event {
id: i32,
sender: ~str,
}
fn read_event<R: Reader>(r: &mut R) -> IoResult<Event> {
let id = if_ok!(r.read_be_i32());
let sender_len = if_ok!(r.read_be_u32());
let sender = if_ok!(r.read_bytes(sender_len as uint));
Ok(Event {
id: id,
sender: str::from_utf8_owned(sender),
})
} It is not designed to be a general purpose "wrap this around anything that gives you an unused result warning" solution. |
Another reddit thread about the sort of thing I'm saying is going to be very common. |
@jfager I don't think allowing There are multiple error handling strategies:
And anything else defined to work with
The |
They're trying to learn how to do I/O idiomatically and without a bunch of ugliness. I point it out because it's an instance of someone reaching for Part of what they're hitting is using Again, this is not an argument for sweeping anything under the rug. It is an argument that I'm sorry I mentioned magic main. I wasn't advocating for it, I just threw it out as something that would remove the immediate problem, but of course it would lead to new ones of its own. Please ignore the suggestion. My current hand-wavy hope is that |
Superseding with #12676, as I don't actually think the problem is just that |
This is fixed in #43301 |
Turn let-else statements into let and match Fixes rust-lang#11906.
Rustup r? `@ghost` changelog: none
try! isn't directly usable in main, because it returns IoResult.
fails with
The text was updated successfully, but these errors were encountered: