-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Closed
Labels
C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.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.T-langRelevant to the language teamRelevant to the language teamdisposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.This issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.The final comment period is finished for this PR / Issue.
Milestone
Description
This is a sub-issue of the larger tracking issue devoted to the ?
in main RFC. It is specifically proposing that we stabilize the behavior that permits main
to have a return type other than ()
. This return type must implement the Termination
trait. The details of the trait itself (including its name and so forth) are not stabilized.
This commits us to the following (each link is to a test):
fn main() -> i32
fn main() -> !
(no test, but here is the impl -- a test is being added in Termination trait in tests #48143)- should never return
fn main() -> Result<(), E>
whereE: Debug
- on
Err
, aDebug
printout occurs - these impls are modified in Restrict the Termination impls to simplify stabilization #48497
- on
fn main() -> Result<!, E>
whereE: Debug
- these impls are modified in Restrict the Termination impls to simplify stabilization #48497
The changes from the RFC are as follows:
- we modified the
Result
impl to useDebug
The following unresolved questions will be resolved:
- The precise initial implementations
- as above
To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.exit codes (discussion)- these are defined as
libc::EXIT_SUCCESS
for "Ok" andlibc::EXIT_FAILURE
for "Err" - except for wasm, where they are currently defined as 0 or 1 for wasm -- this is because those constants are/were not available for wasm
- (they also appear not to be publicly exported? but that is not part of this stabilization)
To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
But the following is not stabilized and free to change:
- the name/location of the
Termination
trait and its methods- likely changing to
std::process::Termination
- likely changing to
- the usage of
-> Result<...>
in unit tests (not yet landed) - the
ErrCode
newtype wrapper for returning a custom error code
--
UPDATE 1: Restricted the set of termination impls as proposed by @scottmcm in #48497.
frewsxcv, U007D, JustAPerson, icefoxen, petamoriken and 6 moreExpHP, ahlinc and schneiderfelipe
Metadata
Metadata
Assignees
Labels
C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.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.T-langRelevant to the language teamRelevant to the language teamdisposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.This issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.The final comment period is finished for this PR / Issue.
Type
Projects
Relationships
Development
Select code repository
Activity
?
inmain
#43301nikomatsakis commentedon Feb 23, 2018
@rfcbot fcp merge
I propose that we stabilize as described above.
rfcbot commentedon Feb 23, 2018
Team member @nikomatsakis has proposed to merge this. The next step is review by the rest of the tagged teams:
Concerns:
delay stabilization of nesting andresolved by Stabilizei32
exit codemain
with non-() return types #48453 (comment)Once a majority of reviewers approve (and none object), 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.
scottmcm commentedon Feb 23, 2018
👍 to stabilizing the basics here.
👎 to some of the allowed return types.
I would propose only stabilizing the following new return types:
!
Result<(), E: Debug>
Result<!, E: Debug>
Thoughts on the others:
Result<Result<!, io::Error>, fmt::Error>
?Result<i32, _>
you run into collisions withOk(1)
andErr(_)
.ExitCode
) toi32
. I could accept justfn main() -> i32
, but it feels like primitive obsession (especially if nesting happens, where it's meaning is far less clear). There were some interesting discussions in the RFC about platform differences here too, which feel like they could be a good fit with the "vision for portability" stuff. And this case in particular isn't needed for the?
-in-main
goals, so can easily wait. As a bonus, I think having a type here that's not a primitive would let us leave the impl but have have the type unstable as the details are figured out.I'll happily make a PR restricting things as above if that'd be helpful.
cramertj commentedon Feb 23, 2018
@rfcbot concern delay stabilization of nesting and
i32
exit codeI feel basically the same way that @scottmcm does-- nesting (e.g.
Result<i32, Error>
) seems confusing and hard to reason about, andi32
seems like it should beExitCode
, perhaps with afrom_raw
method. Can we delay stabilizing these particular impls pending further discussion? I'd love to see!
andResult<!/(), E: Debug>
stabilize.Edit: also
bool
?bkchr commentedon Feb 23, 2018
Yeah it is the opposite,
wasm
is0
and1
and all other platforms uselibc::*
. I have done that, becauselibc::EXIT_SUCCESS
andlibc::EXIT_FAILURE
were not available at that time forwasm
inlibc
.scottmcm commentedon Feb 23, 2018
I noticed that there's
impl Termination for bool
right now too (it's not mentioned in the OP), which I don't think should be part of the minimal set that we stabilize in the first pass.ExpHP commentedon Feb 23, 2018
The RFC says
E: Display
instead ofE: Debug
, and tbh, Display would have been my first choice as well. But I'm sure this has been discussed.Should the RFC be amended to reflect this change, and to explain why Debug is the right choice?
?
inmain
rust-lang/rfcs#1937U007D commentedon Feb 23, 2018
@ExpHP yes, you are correct. Something approaching a summary of thinking around
Display
vsDebug
starts around here: #43301 (comment).withoutboats commentedon Feb 23, 2018
I'm surprised by the concern about nesting - how would someone come to nest results in their main return anyway? It seems like the natural way to implement termination, which has the consequence of enabling this kind of thing, but that it happening in practice would be a non-issue.
we do not usually amend RFCs to cover changes before stabilization. they are design documents for implementation, they dont play any sort of 'constitutional' role.
U007D commentedon Feb 23, 2018
@withoutboats, that is interesting.
If I'm understanding you correctly, by allowing
Result<T, E>
,T
itself may be aResult<U, F>
, but that we should not invent extra machinery to disallow this? That does make a lot of sense...Personally, I was only considering what to allow from the perspective of being conservative; but when being conservative mandates extra logic to specifically disallow certain types, I can see the problem. (Such a limitation could also feel quite arbitrary in blocking some scenario we might not be imagining at the moment...)
Thanks, as usual, for the enlightening perspective. :)
nikomatsakis commentedon Feb 23, 2018
Fixed the wasm reference.
I also thought we might want to limit the impls. Note that we have no mechanism for "feature-gating" impls, so the only way to limit things once we stabilize the basic concept is to remove the stuff we don't want.
I think that supporting only the basics (
!
,()
, andResult<(), E>
) seems good to start -- I anticipate that anyone who wants to use this feature for more complex things will define their own new-type and implementTerminate
themselves. That is certainly what I plan to do in my own code, since I think it's a nice way to separate out the error handling from the rest.If we wanted to go crazy (I don't), I could imagine adding a new trait like
SuccessfulTerminate
and then implementingTerminate
forT
andResult<T, E>
whereT: SuccessfulTerminate
. This avoids nesting but keeps flexibility. (We would implementSuccessfulTerminate
for()
andExitCode
or something.) But it feels like overkill, and it can be readily modeled with your own newtype anyhow.32 remaining items
Rollup merge of rust-lang#49162 - tmandry:stabilize-termination-trait…
Rollup merge of rust-lang#49162 - tmandry:stabilize-termination-trait…
Rollup merge of rust-lang#49162 - tmandry:stabilize-termination-trait…
Rollup merge of rust-lang#49162 - tmandry:stabilize-termination-trait…
()
return types rust-lang/book#1289()
return types rust-lang/rust-by-example#1062scottmcm commentedon Sep 17, 2018
This stabilization happened; closing.