Skip to content
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

Document the Termination trait for main() and test functions #1194

Merged
merged 1 commit into from
Apr 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions src/attributes/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,25 @@ enables the [`test` conditional compilation option].

The *`test` attribute* marks a function to be executed as a test. These
functions are only compiled when in test mode. Test functions must be free,
monomorphic functions that take no arguments, and the return type must be one
of the following:
monomorphic functions that take no arguments, and the return type must implement the [`Termination`] trait, for example:

* `()`
* `Result<(), E> where E: Error`
<!-- * `!` -->
<!-- * Result<!, E> where E: Error` -->

> Note: The implementation of which return types are allowed is determined by
> the unstable [`Termination`] trait.
* `Result<(), E> where E: Debug`
* `!`
<!-- * Result<!, E> where E: Debug` -->

<!-- If the previous section needs updating (from "must take no arguments"
onwards, also update it in the crates-and-source-files.md file -->

> Note: The test mode is enabled by passing the `--test` argument to `rustc`
> or using `cargo test`.

Tests that return `()` pass as long as they terminate and do not panic. Tests
that return a `Result<(), E>` pass as long as they return `Ok(())`. Tests that
do not terminate neither pass nor fail.
The test harness calls the returned value's [`report`] method, and classifies the test as passed or failed depending on whether the resulting [`ExitCode`] represents successful termination.
In particular:
* Tests that return `()` pass as long as they terminate and do not panic.
* Tests that return a `Result<(), E>` pass as long as they return `Ok(())`.
* Tests that return `ExitCode::SUCCESS` pass, and tests that return `ExitCode::FAILURE` fail.
* Tests that do not terminate neither pass nor fail.
Comment on lines +27 to +30
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm concerned this may be over-specifying the behavior. There's a bit of an awkward separation between "Rust the language" and "the standard library". The reference typically tends to focus on just the language behavior, and not delve into the standard library's implementation.

Also, I'm not really comfortable with specifying the non-termination behavior. I would consider that a failure, and it is possible in the future that either libtest or cargo could have some sort of timeout controls which would consider the test to fail.

I think leaving this up to the Termination docs in the standard library should be sufficient.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Tests that do not terminate neither pass nor fail." sentence was present already; this PR only moves it.


```rust
# use std::io;
Expand Down Expand Up @@ -85,5 +84,7 @@ fn mytest() {
[_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
[_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
[`Termination`]: ../../std/process/trait.Termination.html
[`report`]: ../../std/process/trait.Termination.html#tymethod.report
[`test` conditional compilation option]: ../conditional-compilation.md#test
[attributes]: ../attributes.md
[`ExitCode`]: ../../std/process/struct.ExitCode.html
31 changes: 24 additions & 7 deletions src/crates-and-source-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,30 @@ This section has been moved to the [Preludes chapter](names/preludes.md).
A crate that contains a `main` [function] can be compiled to an executable. If a
`main` function is present, it must take no arguments, must not declare any
[trait or lifetime bounds], must not have any [where clauses], and its return
type must be one of the following:
type must implement the [`Termination`] trait.

* `()`
* `Result<(), E> where E: Error`
<!-- * `!` -->
<!-- * Result<!, E> where E: Error` -->
```rust
fn main() {}
```
```rust
fn main() -> ! {
std::process::exit(0);
}
```
```rust
fn main() -> impl std::process::Termination {
std::process::ExitCode::SUCCESS
}
```

> Note: The implementation of which return types are allowed is determined by
> the unstable [`Termination`] trait.
> **Note**: Types with implementations of [`Termination`] in the standard library include:
>
> * `()`
> * [`!`]
> * [`ExitCode`]
> * `Result<(), E> where E: Debug`
> * `Result<Infallible, E> where E: Debug`
<!-- > * Result<!, E> where E: Debug` -->

<!-- If the previous section needs updating (from "must take no arguments"
onwards, also update it in the testing.md file -->
Expand Down Expand Up @@ -143,11 +158,13 @@ or `_` (U+005F) characters.
in the Owens and Flatt module system, or a *configuration* in Mesa.

[Unicode alphanumeric]: ../std/primitive.char.html#method.is_alphanumeric
[`!`]: types/never.md
[_InnerAttribute_]: attributes.md
[_Item_]: items.md
[_MetaNameValueStr_]: attributes.md#meta-item-attribute-syntax
[_shebang_]: https://en.wikipedia.org/wiki/Shebang_(Unix)
[_utf8 byte order mark_]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
[`ExitCode`]: ../std/process/struct.ExitCode.html
[`Termination`]: ../std/process/trait.Termination.html
[attribute]: attributes.md
[attributes]: attributes.md
Expand Down
7 changes: 7 additions & 0 deletions src/special-types-and-traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ The [`Sync`] trait indicates that a value of this type is safe to share between
multiple threads. This trait must be implemented for all types used in
immutable [`static` items].

## `Termination`

The [`Termination`] trait indicates the acceptable return types for the [main function] and [test functions].

## Auto traits

The [`Send`], [`Sync`], [`Unpin`], [`UnwindSafe`], and [`RefUnwindSafe`] traits are _auto
Expand Down Expand Up @@ -151,6 +155,7 @@ These implicit `Sized` bounds may be relaxed by using the special `?Sized` bound
[`std::cmp`]: ../std/cmp/index.html
[`std::marker::PhantomData<T>`]: ../std/marker/struct.PhantomData.html
[`std::ops`]: ../std/ops/index.html
[`Termination`]: ../std/process/trait.Termination.html
[`UnwindSafe`]: ../std/panic/trait.UnwindSafe.html
[`Sync`]: ../std/marker/trait.Sync.html
[`Unpin`]: ../std/marker/trait.Unpin.html
Expand All @@ -168,11 +173,13 @@ These implicit `Sized` bounds may be relaxed by using the special `?Sized` bound
[implementation items]: items/implementations.md
[indexing expressions]: expressions/array-expr.md#array-and-slice-indexing-expressions
[interior mutability]: interior-mutability.md
[main function]: crates-and-source-files.md#main-functions
[Methods]: items/associated-items.md#associated-functions-and-methods
[method resolution]: expressions/method-call-expr.md
[operators]: expressions/operator-expr.md
[orphan rules]: items/implementations.md#trait-implementation-coherence
[`static` items]: items/static-items.md
[test functions]: attributes/testing.md#the-test-attribute
[the standard library]: ../std/index.html
[trait object]: types/trait-object.md
[Tuples]: types/tuple.md
Expand Down