Rollup merge of #48143 - nikomatsakis:termination_trait_in_tests, r=eddyb
Termination trait in tests Support the `Termination` trait in unit tests (cc https://github.com/rust-lang/rust/issues/43301) Also, a drive-by fix for #47075. This is joint work with @bkchr.
This commit is contained in:
@@ -500,11 +500,6 @@ mod memchr;
|
||||
// The runtime entry point and a few unstable public functions used by the
|
||||
// compiler
|
||||
pub mod rt;
|
||||
// The trait to support returning arbitrary types in the main function
|
||||
mod termination;
|
||||
|
||||
#[unstable(feature = "termination_trait", issue = "43301")]
|
||||
pub use self::termination::Termination;
|
||||
|
||||
// Include a number of private modules that exist solely to provide
|
||||
// the rustdoc documentation for primitive types. Using `include!`
|
||||
|
||||
@@ -1392,6 +1392,73 @@ pub fn id() -> u32 {
|
||||
::sys::os::getpid()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod exit {
|
||||
pub const SUCCESS: i32 = 0;
|
||||
pub const FAILURE: i32 = 1;
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod exit {
|
||||
use libc;
|
||||
pub const SUCCESS: i32 = libc::EXIT_SUCCESS;
|
||||
pub const FAILURE: i32 = libc::EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/// A trait for implementing arbitrary return types in the `main` function.
|
||||
///
|
||||
/// The c-main function only supports to return integers as return type.
|
||||
/// So, every type implementing the `Termination` trait has to be converted
|
||||
/// to an integer.
|
||||
///
|
||||
/// The default implementations are returning `libc::EXIT_SUCCESS` to indicate
|
||||
/// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned.
|
||||
#[cfg_attr(not(test), lang = "termination")]
|
||||
#[unstable(feature = "termination_trait_lib", issue = "43301")]
|
||||
#[rustc_on_unimplemented =
|
||||
"`main` can only return types that implement {Termination}, not `{Self}`"]
|
||||
pub trait Termination {
|
||||
/// Is called to get the representation of the value as status code.
|
||||
/// This status code is returned to the operating system.
|
||||
fn report(self) -> i32;
|
||||
}
|
||||
|
||||
#[unstable(feature = "termination_trait_lib", issue = "43301")]
|
||||
impl Termination for () {
|
||||
fn report(self) -> i32 { exit::SUCCESS }
|
||||
}
|
||||
|
||||
#[unstable(feature = "termination_trait_lib", issue = "43301")]
|
||||
impl<T: Termination, E: fmt::Debug> Termination for Result<T, E> {
|
||||
fn report(self) -> i32 {
|
||||
match self {
|
||||
Ok(val) => val.report(),
|
||||
Err(err) => {
|
||||
eprintln!("Error: {:?}", err);
|
||||
exit::FAILURE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "termination_trait_lib", issue = "43301")]
|
||||
impl Termination for ! {
|
||||
fn report(self) -> i32 { unreachable!(); }
|
||||
}
|
||||
|
||||
#[unstable(feature = "termination_trait_lib", issue = "43301")]
|
||||
impl Termination for bool {
|
||||
fn report(self) -> i32 {
|
||||
if self { exit::SUCCESS } else { exit::FAILURE }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "termination_trait_lib", issue = "43301")]
|
||||
impl Termination for i32 {
|
||||
fn report(self) -> i32 {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
|
||||
mod tests {
|
||||
use io::prelude::*;
|
||||
|
||||
@@ -68,7 +68,7 @@ fn lang_start_internal(main: &(Fn() -> i32 + Sync + ::panic::RefUnwindSafe),
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[lang = "start"]
|
||||
fn lang_start<T: ::termination::Termination + 'static>
|
||||
fn lang_start<T: ::process::Termination + 'static>
|
||||
(main: fn() -> T, argc: isize, argv: *const *const u8) -> isize
|
||||
{
|
||||
lang_start_internal(&move || main().report(), argc, argv)
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use fmt::Debug;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod exit {
|
||||
pub const SUCCESS: i32 = 0;
|
||||
pub const FAILURE: i32 = 1;
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod exit {
|
||||
use libc;
|
||||
pub const SUCCESS: i32 = libc::EXIT_SUCCESS;
|
||||
pub const FAILURE: i32 = libc::EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/// A trait for implementing arbitrary return types in the `main` function.
|
||||
///
|
||||
/// The c-main function only supports to return integers as return type.
|
||||
/// So, every type implementing the `Termination` trait has to be converted
|
||||
/// to an integer.
|
||||
///
|
||||
/// The default implementations are returning `libc::EXIT_SUCCESS` to indicate
|
||||
/// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned.
|
||||
#[cfg_attr(not(test), lang = "termination")]
|
||||
#[unstable(feature = "termination_trait", issue = "43301")]
|
||||
#[rustc_on_unimplemented =
|
||||
"`main` can only return types that implement {Termination}, not `{Self}`"]
|
||||
pub trait Termination {
|
||||
/// Is called to get the representation of the value as status code.
|
||||
/// This status code is returned to the operating system.
|
||||
fn report(self) -> i32;
|
||||
}
|
||||
|
||||
#[unstable(feature = "termination_trait", issue = "43301")]
|
||||
impl Termination for () {
|
||||
fn report(self) -> i32 { exit::SUCCESS }
|
||||
}
|
||||
|
||||
#[unstable(feature = "termination_trait", issue = "43301")]
|
||||
impl<T: Termination, E: Debug> Termination for Result<T, E> {
|
||||
fn report(self) -> i32 {
|
||||
match self {
|
||||
Ok(val) => val.report(),
|
||||
Err(err) => {
|
||||
eprintln!("Error: {:?}", err);
|
||||
exit::FAILURE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "termination_trait", issue = "43301")]
|
||||
impl Termination for ! {
|
||||
fn report(self) -> i32 { unreachable!(); }
|
||||
}
|
||||
|
||||
#[unstable(feature = "termination_trait", issue = "43301")]
|
||||
impl Termination for bool {
|
||||
fn report(self) -> i32 {
|
||||
if self { exit::SUCCESS } else { exit::FAILURE }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "termination_trait", issue = "43301")]
|
||||
impl Termination for i32 {
|
||||
fn report(self) -> i32 {
|
||||
self
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user