Skip to content

Commit 2da08dc

Browse files
authored
Rollup merge of rust-lang#48143 - nikomatsakis:termination_trait_in_tests, 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.
2 parents 2171d35 + 10f7c11 commit 2da08dc

File tree

14 files changed

+300
-147
lines changed

14 files changed

+300
-147
lines changed

src/librustc_driver/driver.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,8 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
818818
&mut resolver,
819819
sess.opts.test,
820820
krate,
821-
sess.diagnostic())
821+
sess.diagnostic(),
822+
&sess.features.borrow())
822823
});
823824

824825
// If we're actually rustdoc then there's no need to actually compile

src/libstd/lib.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -500,11 +500,6 @@ mod memchr;
500500
// The runtime entry point and a few unstable public functions used by the
501501
// compiler
502502
pub mod rt;
503-
// The trait to support returning arbitrary types in the main function
504-
mod termination;
505-
506-
#[unstable(feature = "termination_trait", issue = "43301")]
507-
pub use self::termination::Termination;
508503

509504
// Include a number of private modules that exist solely to provide
510505
// the rustdoc documentation for primitive types. Using `include!`

src/libstd/process.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,6 +1392,73 @@ pub fn id() -> u32 {
13921392
::sys::os::getpid()
13931393
}
13941394

1395+
#[cfg(target_arch = "wasm32")]
1396+
mod exit {
1397+
pub const SUCCESS: i32 = 0;
1398+
pub const FAILURE: i32 = 1;
1399+
}
1400+
#[cfg(not(target_arch = "wasm32"))]
1401+
mod exit {
1402+
use libc;
1403+
pub const SUCCESS: i32 = libc::EXIT_SUCCESS;
1404+
pub const FAILURE: i32 = libc::EXIT_FAILURE;
1405+
}
1406+
1407+
/// A trait for implementing arbitrary return types in the `main` function.
1408+
///
1409+
/// The c-main function only supports to return integers as return type.
1410+
/// So, every type implementing the `Termination` trait has to be converted
1411+
/// to an integer.
1412+
///
1413+
/// The default implementations are returning `libc::EXIT_SUCCESS` to indicate
1414+
/// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned.
1415+
#[cfg_attr(not(test), lang = "termination")]
1416+
#[unstable(feature = "termination_trait_lib", issue = "43301")]
1417+
#[rustc_on_unimplemented =
1418+
"`main` can only return types that implement {Termination}, not `{Self}`"]
1419+
pub trait Termination {
1420+
/// Is called to get the representation of the value as status code.
1421+
/// This status code is returned to the operating system.
1422+
fn report(self) -> i32;
1423+
}
1424+
1425+
#[unstable(feature = "termination_trait_lib", issue = "43301")]
1426+
impl Termination for () {
1427+
fn report(self) -> i32 { exit::SUCCESS }
1428+
}
1429+
1430+
#[unstable(feature = "termination_trait_lib", issue = "43301")]
1431+
impl<T: Termination, E: fmt::Debug> Termination for Result<T, E> {
1432+
fn report(self) -> i32 {
1433+
match self {
1434+
Ok(val) => val.report(),
1435+
Err(err) => {
1436+
eprintln!("Error: {:?}", err);
1437+
exit::FAILURE
1438+
}
1439+
}
1440+
}
1441+
}
1442+
1443+
#[unstable(feature = "termination_trait_lib", issue = "43301")]
1444+
impl Termination for ! {
1445+
fn report(self) -> i32 { unreachable!(); }
1446+
}
1447+
1448+
#[unstable(feature = "termination_trait_lib", issue = "43301")]
1449+
impl Termination for bool {
1450+
fn report(self) -> i32 {
1451+
if self { exit::SUCCESS } else { exit::FAILURE }
1452+
}
1453+
}
1454+
1455+
#[unstable(feature = "termination_trait_lib", issue = "43301")]
1456+
impl Termination for i32 {
1457+
fn report(self) -> i32 {
1458+
self
1459+
}
1460+
}
1461+
13951462
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
13961463
mod tests {
13971464
use io::prelude::*;

src/libstd/rt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ fn lang_start_internal(main: &(Fn() -> i32 + Sync + ::panic::RefUnwindSafe),
6868

6969
#[cfg(not(test))]
7070
#[lang = "start"]
71-
fn lang_start<T: ::termination::Termination + 'static>
71+
fn lang_start<T: ::process::Termination + 'static>
7272
(main: fn() -> T, argc: isize, argv: *const *const u8) -> isize
7373
{
7474
lang_start_internal(&move || main().report(), argc, argv)

src/libstd/termination.rs

Lines changed: 0 additions & 77 deletions
This file was deleted.

src/libsyntax/ext/build.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -319,14 +319,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
319319
types: Vec<P<ast::Ty>>,
320320
bindings: Vec<ast::TypeBinding> )
321321
-> ast::Path {
322-
use syntax::parse::token;
323-
324322
let last_identifier = idents.pop().unwrap();
325323
let mut segments: Vec<ast::PathSegment> = Vec::new();
326-
if global &&
327-
!idents.first().map_or(false, |&ident| token::Ident(ident).is_path_segment_keyword()) {
328-
segments.push(ast::PathSegment::crate_root(span));
329-
}
330324

331325
segments.extend(idents.into_iter().map(|i| ast::PathSegment::from_ident(i, span)));
332326
let parameters = if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
@@ -335,7 +329,9 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
335329
None
336330
};
337331
segments.push(ast::PathSegment { identifier: last_identifier, span, parameters });
338-
ast::Path { span, segments }
332+
let path = ast::Path { span, segments };
333+
334+
if global { path.default_to_global() } else { path }
339335
}
340336

341337
/// Constructs a qualified path.

0 commit comments

Comments
 (0)