reference icon indicating copy to clipboard operation
reference copied to clipboard

Document the effect of main's return value?

Open mattheww opened this issue 3 years ago • 8 comments

https://github.com/rust-lang/reference/pull/1194#issuecomment-1101856264 suggests documenting how main()s return value affects the process's exit status.

I think the Reference doesn't currently have anything to say about what happens after main() returns.

I suggest adding a section in runtime.md saying roughly the following:

  • When (if) main() returns, the runtime calls report() on its result (which necessarily implements Termination), which gives an ExitCode.

  • The runtime uses that ExitCode in a platform-specific way to report information to the environment hosting the Rust program.

  • Note: on Unix-like systems and Windows, the ExitCode determines the process's exit status

Further, I think some part of Rust's documentation ought to be saying that, on Unix-like systems and Windows, ExitCode::SUCCESS leads to exit status 0, and ExitCode::FAILURE leads to exit status 1 (because we have to expect that users will rely on that behaviour). I think that part would be better in the standard library docs, but it isn't currently there.

I think it's important to say that report() is called, because that's what has the side-effect of printing a message to standard error (in the case where the returned value was a Result<_, Debug>).

So I think ideally the standard library docs would have entries for the specific Termination impls, saying how each of them behaves.

I think this approach would avoid the worry expressed in rust-lang/rust#93448: a no_std binary won't be using the Termination impls for Result<_, Debug>, because those are in std.

mattheww avatar Apr 19 '22 21:04 mattheww

This sounds reasonable to me. The reference has historically not touched on platform-specifics like this, and has also somewhat ignored life before/after main as well. But I think making these statements about Termination seem like a good, small step.

@rust-lang/lang I would appreciate if someone could weigh in here. Are you OK with the reference specifying the exit-status behavior with respect to the Termination trait as discussed above?

ehuss avatar Apr 21 '22 22:04 ehuss

Despite Termination being a library trait, it's used in the language "runtime" code that runs after main, so I think it should be documented in the reference.

And we should explicitly document how we pass through values.

joshtriplett avatar May 03 '22 17:05 joshtriplett

Also, a bit more context from the lang team meeting. When we discussed this we agreed that we want the reference to include documentation about the runtime half of the return from main system. Such as specifying how it interacts with the Termination trait (calling report) and how it passes along the ExitCode, but that we should leave the documentation about the library APIs being consumed in the library API docs. Such as any indication of what report does for specific types or what values ExitCode::FAILURE/ExitCode::SUCCESS map to on specific platforms should live in the API docs, and the reference should only include a small section indicating that this additional information lives in the API docs with cross links to those docs.

yaahc avatar May 03 '22 18:05 yaahc

RE. the above (w/ the context from reading the minutes of that aformentioned meeting after the fact), C requires that a status code 0 (and incidentally also EXIT_SUCCESS which may be the same or distinct) mean "successful" termination, though it doesn't require anything other than EXIT_FAILURE to mean "failed" termination.

chorman0773 avatar May 03 '22 18:05 chorman0773

RE. the above (w/ the context from reading the minutes of that aformentioned meeting after the fact), C requires that a status code 0 (and incidentally also EXIT_SUCCESS which may be the same or distinct) mean "successful" termination, though it doesn't require anything other than EXIT_FAILURE to mean "failed" termination.

I don't think we'd necessarily want to copy C here, but we did discuss whether the u8 value an ExitCode is constructed from in rust should be distinct from the value it gets translated to for any specific platform. More concretely, the idea being that constructing an ExitCode from 0u8 will always give you ExitCode::SUCCESS, and any other value would always give you ExitCode::FAILURE or something equivalent, but ExitCode::SUCCESS doesn't necessarily need to map to 0 on any specific platform. The ultimate goal here is that we want to be as flexible as possible over what platform APIs we can abstract over, should , for example, some future rust based OS come along with a radically different interpretation of exit codes, we don't want to restrict their possible design space.

yaahc avatar May 03 '22 18:05 yaahc

More concretely, the idea being that constructing an ExitCode from 0u8 will always give you ExitCode::SUCCESS, and any other value would always give you ExitCode::FAILURE, but ExitCode::SUCCESS doesn't necessarily need to map to 0 on any specific platform.

We should be able to construct arbitrary ExitCodes, though.

One of the reasons I believe for ExitCode (and indeed, one reason I need it) is to return arbitrary status's to the environment, thus communicating with w/e program may be waiting. I'd expect ExitCode::new(20u8) to return 20 to the environment, not 1, usually because I've prearranged the value "20" to have some special meaning with something I know will be running the program (for example, for cargo-native-install, a program that does an autotools-like install for cargo projects, an exit status of 20 from a run target means "Skipped.Target, Report, Continue Instalation", whereas 1 means "Fatal install Error, Report, Abort Installation").

On Tue, 3 May 2022 at 14:43, Jane Lusby @.***> wrote:

RE. the above (w/ the context from reading the minutes of that aformentioned meeting after the fact), C requires that a status code 0 (and incidentally also EXIT_SUCCESS which may be the same or distinct) mean "successful" termination, though it doesn't require anything other than EXIT_FAILURE to mean "failed" termination.

I don't think we'd necessarily want to copy C here, but we did discuss whether the u8 value an ExitCode is constructed from in rust should be distinct from the value it gets translated to for any specific platform. More concretely, the idea being that constructing an ExitCode from 0u8 will always give you ExitCode::SUCCESS, and any other value would always give you ExitCode::FAILURE, but ExitCode::SUCCESS doesn't necessarily need to map to 0 on any specific platform.

— Reply to this email directly, view it on GitHub https://github.com/rust-lang/reference/issues/1196#issuecomment-1116440672, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABGLD232NFAUGND7H5VK4WTVIFXWLANCNFSM5T2CGF5A . You are receiving this because you commented.Message ID: @.***>

chorman0773 avatar May 04 '22 10:05 chorman0773

I think there's been some confusion here. I didn't mean to imply that ExitCode::from(20u8) would always map directly to ExitCode::FAILURE. I am just trying to make sure that cross platform assumptions around constructing ExitCodes hold up as best as possible when using the cross platform interface. I don't want people's code that assumes ExitCode::from(0) is always success to completely fail to work on platforms where they decided to have a different sentinel value represent success. In your example, the only time I expect ExitCode::from(20) would produce ExitCode::FAILURE is when you're running on a platform where ExitCode::SUCCESS == ExitCode(20), otherwise I'd just expect us to forward along the ExitCode(20) as intended.

Then, if we run into a situation where someone is running on a platform where ExitCode(0) represents a specific failure that they need to be able to represent we can add a platform specific API for constructing exit codes directly from that platform's expected representation, with docs detailing the exact ways the codes differ on that platform, and do so in a way that ensures that non-cross-platform code never compiles on other platforms.

yaahc avatar May 04 '22 16:05 yaahc

We discussed this again in today's @rust-lang/lang meeting, and we want to confirm that we'd be happy to have the lang/runtime aspects of this documented in the reference. (The library semantics should remain in the library docs.)

joshtriplett avatar May 10 '22 17:05 joshtriplett