Skip to content

Commit

Permalink
Rollup merge of rust-lang#48143 - nikomatsakis:termination_trait_in_t…
Browse files Browse the repository at this point in the history
…ests, r=eddyb

Termination trait in tests

Support the `Termination` trait in unit tests (cc rust-lang#43301)

Also, a drive-by fix for rust-lang#47075.

This is joint work with @bkchr.
  • Loading branch information
Manishearth authored Feb 24, 2018
2 parents 2171d35 + 10f7c11 commit 2da08dc
Show file tree
Hide file tree
Showing 14 changed files with 300 additions and 147 deletions.
3 changes: 2 additions & 1 deletion src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,8 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
&mut resolver,
sess.opts.test,
krate,
sess.diagnostic())
sess.diagnostic(),
&sess.features.borrow())
});

// If we're actually rustdoc then there's no need to actually compile
Expand Down
5 changes: 0 additions & 5 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!`
Expand Down
67 changes: 67 additions & 0 deletions src/libstd/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
77 changes: 0 additions & 77 deletions src/libstd/termination.rs

This file was deleted.

10 changes: 3 additions & 7 deletions src/libsyntax/ext/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,14 +319,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
types: Vec<P<ast::Ty>>,
bindings: Vec<ast::TypeBinding> )
-> ast::Path {
use syntax::parse::token;

let last_identifier = idents.pop().unwrap();
let mut segments: Vec<ast::PathSegment> = Vec::new();
if global &&
!idents.first().map_or(false, |&ident| token::Ident(ident).is_path_segment_keyword()) {
segments.push(ast::PathSegment::crate_root(span));
}

segments.extend(idents.into_iter().map(|i| ast::PathSegment::from_ident(i, span)));
let parameters = if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
Expand All @@ -335,7 +329,9 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
None
};
segments.push(ast::PathSegment { identifier: last_identifier, span, parameters });
ast::Path { span, segments }
let path = ast::Path { span, segments };

if global { path.default_to_global() } else { path }
}

/// Constructs a qualified path.
Expand Down
Loading

0 comments on commit 2da08dc

Please sign in to comment.