Repository navigation
Closed
Labels
B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.Blocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCE-help-wantedCall for participation: Help is requested to fix this issue.Call for participation: Help is requested to fix this issue.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.S-tracking-design-concernsStatus: There are blocking design concerns.Status: There are blocking design concerns.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamT-libs-api[DEPRECATED; DO NOT USE][DEPRECATED; DO NOT USE]
Description
This is a tracking issue for the RFC "? in main" (rust-lang/rfcs#1937).
Steps:
- Implement the RFC (mentoring instructions can be found here).
-
?inmain(Implements RFC 1937:?inmain#46479) -
?in doctest -
?in#[test]
-
- Adjust documentation (see instructions on forge)
- Stabilization PR (see instructions on forge)
Stabilizations:
- Stabilize
mainwith non-() return types (Stabilizemainwith non-() return types #48453) Merged in Stabilize termination_trait, split out termination_trait_test #49162 - Stabilize unit tests with non-() return types (Stabilize unit tests with non-
()return type #48854)
Related issues:
- Error message for unit tests is not great (error message when unit test type does not implement
Terminationis ungreat #50291)
Unresolved questions:
- The name of the trait being introduced
- The precise initial implementations
- this will be stabilized by Stabilize
mainwith non-() return types #48453
- this will be stabilized by Stabilize
- exit codes (discussion) Moved to a separate tracking issue, Tracking issue for std::process::ExitCode (feature process_exitcode_placeholder) #48711
this will be stabilized by Stabilizeno longer true after Restrict the Termination impls to simplify stabilization #48497mainwith non-() return types #48453
Reacted by Tim Hutt, Nagy Tibor, Pascal Hertleif, m0n0chr0m3, Joseph Lenton, runiq, Weiyuan Wu, neXos, Stanislav Tkach, Eric Shimizu Karbstein and 5 more
Reacted by Jon Gjengset, Alex Burka, Steve Klabnik, Matthew, Niklas Fiekas, Wayne Nilsen, Techcable, Andy Hayden, Hadrien G., Chris and 11 more
Reacted by Felipe S. S. Schneider
Reacted by Felipe S. S. Schneider
Metadata
Metadata
Assignees
Labels
B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.Blocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCE-help-wantedCall for participation: Help is requested to fix this issue.Call for participation: Help is requested to fix this issue.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.S-tracking-design-concernsStatus: There are blocking design concerns.Status: There are blocking design concerns.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamT-libs-api[DEPRECATED; DO NOT USE][DEPRECATED; DO NOT USE]
Activity
ketsuban commentedon Jul 18, 2017
This comment by @Screwtapello seems to have been made too close to the end of FCP for any alterations to be made to the RFC in response to it.
In short: the RFC proposes returning 2 on failure on grounds which, while well-founded, are obscure and produce a slightly unusual result; the least surprising thing is to return 1 when the program has no indication it wants any more detail than just success or failure. Is this sufficiently bikesheddy that it can be discussed without it feeling like we're perverting the RFC process, or are we now locked into this specific implementation detail?
Screwtapello commentedon Jul 18, 2017
This is specifically about the case when a sub-process (implemented in Rust) has no information to give, beyond a binary "everything's fine"/"something went wrong".
NoraCodes commentedon Jul 18, 2017
That behavior is always extremely dependent on the program being called except in that non-zero means failure. Given that
std::process::exitwith a main-function wrapper and a lookup table is going to remain the best option for those who want a more articulate exit status no matter what is done, this seems like a mostly insignificant detail.glaebhoerl commentedon Jul 18, 2017
I think the exit code should be added to the unresolved questions list. @zackw also opened a related internals thread.
liigo commentedon Aug 11, 2017
Many people agree that the exit code should be
1on failure (instead of2):https://www.reddit.com/r/rust/comments/6nxg6t/the_rfc_using_in_main_just_got_merged/
225 remaining items
Stargateur commentedon Apr 7, 2022
@joshtriplett Why would you oppose to let such scenario be handle by
exit()feature ?joshtriplett commentedon Apr 7, 2022
Because exit codes are a well-established mechanism that I'd like to see integrated with
?-based error handling, and I don't see any reason not to offer first-class support for them. And becauseexitdoesn't necessarily allow a program's cleanup to run, whereas returning from main does.Kixunil commentedon Apr 7, 2022
My favorite example when multiple error codes are useful:
The behavior of
grepis documented so the code above is sensible. Pulling this out of stderr would be very annoying and possibly unreliable. A Rust program should be able to support something similar.lnicola commentedon Apr 7, 2022
And error messages are often localized.
BurntSushi commentedon Apr 7, 2022
Here's the relevant code:
https://github.com/BurntSushi/ripgrep/blob/ced5b92aa93eb47e892bd2fd26ab454008721730/crates/core/main.rs#L67-L73
I don't think it's for legacy. @Kixunil gave a good example of why you really want to distinguish between "success," "no match" and "error." If
?-in-main doesn't support returning exit codes beyond "success" or "failure," then yeah, I would just keep usingprocess::exit.I read the comments above and I don't see any compelling reason for limiting ourselves to "success" or "failure." The docs can clearly state that
0tends to mean success, but there is otherwise no agreed upon standard for what other numbers mean. So yeah, I think we should at minimum provide a way for constructing anExitCodefrom au8.Lucretiel commentedon Apr 7, 2022
I'll also shout out git bisect, which is the best example I know of a program that consumes error codes from another program. Git bisect wants to find the first commit that fails to pass a test (presumably where a bug was introduced), so you give it a command and it performs a binary search, running the command in a loop on various commits. It interprets 0 as "build success", 125 as "skip / not testable", 1-127 as "build failure", and 128+ as "stop bisecting". It's a really excellent system for tracking down when a particular bug was introduced in a long commit history.
mathstuf commentedon Apr 7, 2022
It's also relevant to skipping tests in various test suites (
autoconfandautomakeuse 77 to indicate that a test should skip. See this pre-RFC IRLO thread for more prior art there.Stargateur commentedon Apr 7, 2022
That false, exit code are not at all well established mechanism, they are on the contrary implemented behaviour so it's hard to rely on them outside of linux and even on linux it's a meh and some system doesn't support them at all. I listed some reason to not offer first class support for them. I think we must clearly document it as implementation behaviour.
My point was to use exit at the end of the main, I think it's should be the same cleanup degree, but agree this is a big con to
exit().I believe grep example is a very bad one of using error code, other are fine but on grep make the program return an error for not found is rather counter intuitive and probably have been source of bug over time. A bash script generally want to stop at any error using:
Using grep in a bash script with this would make the script stop for empty result, quite weird IMO. Any code/script that want to stop at the first error would be annoying by the grep behaviour. I think an grep option that return the number of match would be better. I don't know if this option exist but something like this
count=$(grep --count "$needle" "$haystack_file")andif [ "$count" -eq "0" ];. (combine with an option that stop at first result if you only want to know if there is at least one match)Obviously use stderr in a script require the program to have an option to output machine like error message, json or whatever. Something easy to parse and documented. Quite similar to Cargo metadata output.
I didn't say they was no use-case, my point was about let the job be handle by
exit()and that I think they are better way to report result than using error code. I'm also afraid this would be used badly. But I don't strongly oppose, I just raise concern. And I'm quite alone in this team so be it.yaahc commentedon Apr 7, 2022
I'm gonna go out on a limb and say that this is a shortcoming of error handling in bash, not grep. The fact that bash makes properly handling error cases so incredibly difficult was a big factor in me getting further involved in Rust and Rust error handling in particular. I think you're absolutely right in that the state of exit codes is not okay, but this system exists, people rely on it, and we already support it.
i32is the defacto interface by which processes report errors to each other on most platforms and while I would love to see that replaced by something better in the future, I do not think parsingstderris the fix.Kixunil commentedon Apr 8, 2022
Can you give some examples? I've been using various Linux distributions for ~14 years and never came across one that didn't support exit codes. It's true that very few programs do stupid shit around exit codes (especially not using them) but programs generally do stupid shit so that's no surprise. By limiting the API we would encourage more stupid shit, not less.
Agree with @yaahc that
set -eis<redacted slur>error handling. (I have some unpleasant experiences with it and generally avoid it.)yaahc commentedon Apr 8, 2022
@Kixunil please refrain from using ableist slurs.
Stargateur commentedon Apr 8, 2022
Sorry I wasn't clear, linux only take 8 bits of int of
exit(), that why the current plan is to implFrom<u8> for ExitCode. This is because linux use the rest of the int as bitfield for other info. Windows doesn't do that so you don't have same value of linux for anything > 255 and negative value are unclear too. Here we have a big difference between two major OS, then yaahc said "i32 is the defacto interface by which processes report errors to each other on most platforms" that IMO false it's aintso this isn't clear about being a i32 or other int size. Specially on embedded system where int could be 16 bits. For system that doesn't support it I don't have a list but yaahc said Wasm seem to not allow it.In my opinion the current limit with u8 is a nice idea, wasm limit is not a big deal and almost all systems would handle at least u8 value.
I'm not sure I understand the same thing, English is not my best and I have no idea what "I'm gonna go out on a limb " mean. But I believe the point of yaahc was more about bash being bad at error handle in general, even just write a correct
ifin bash is complicated.yaahc commentedon Apr 8, 2022
oh, sorry about that. "going out on a limb" is a saying that refers to "climbing out onto tree branch (limb)" with the idea that the branch would not do a good job supporting you and may break out from under you at any moment. In this situation, the branch represents the position I'm taking or argument I'm making, and I used that phrase to indicate that I felt I was risking push back by being critical of another language and that this is the kind of argument I normally would not make, at least not in issues like this.
joshtriplett commentedon May 15, 2023
Every usage of this tracking issue in rust-lang/rust has been stabilized. There may be further work we want to do on
?inmainin the future, but the work tracked by this tracking issue seems to be done.