Skip to content

Commit e446f70

Browse files
committed
put the "unit test" logic into libtest
Also make `std::termination` module public and rename feature. The lib feature needs a different name from the language feature.
1 parent 0625d4c commit e446f70

File tree

6 files changed

+47
-54
lines changed

6 files changed

+47
-54
lines changed

src/libstd/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -501,11 +501,10 @@ mod memchr;
501501
// The runtime entry point and a few unstable public functions used by the
502502
// compiler
503503
pub mod rt;
504-
// The trait to support returning arbitrary types in the main function
505-
mod termination;
506504

505+
// The trait to support returning arbitrary types in the main function
507506
#[unstable(feature = "termination_trait", issue = "43301")]
508-
pub use self::termination::Termination;
507+
pub mod termination;
509508

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

src/libstd/termination.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
//! Defines the meaning of the return value from `main`, and hence
12+
//! controls what happens in a Rust program after `main` returns.
13+
1114
use fmt::Debug;
15+
1216
#[cfg(target_arch = "wasm32")]
1317
mod exit {
1418
pub const SUCCESS: i32 = 0;
@@ -30,28 +34,21 @@ mod exit {
3034
/// The default implementations are returning `libc::EXIT_SUCCESS` to indicate
3135
/// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned.
3236
#[cfg_attr(not(test), lang = "termination")]
33-
#[unstable(feature = "termination_trait", issue = "43301")]
37+
#[unstable(feature = "termination_trait_lib", issue = "43301")]
3438
#[rustc_on_unimplemented =
3539
"`main` can only return types that implement {Termination}, not `{Self}`"]
3640
pub trait Termination {
3741
/// Is called to get the representation of the value as status code.
3842
/// This status code is returned to the operating system.
3943
fn report(self) -> i32;
40-
41-
/// Invoked when unit tests terminate. Should panic if the unit
42-
/// test is considered a failure. By default, invokes `report()`
43-
/// and checks for a `0` result.
44-
fn assert_unit_test_successful(self) where Self: Sized {
45-
assert_eq!(self.report(), 0);
46-
}
4744
}
4845

49-
#[unstable(feature = "termination_trait", issue = "43301")]
46+
#[unstable(feature = "termination_trait_lib", issue = "43301")]
5047
impl Termination for () {
5148
fn report(self) -> i32 { exit::SUCCESS }
5249
}
5350

54-
#[unstable(feature = "termination_trait", issue = "43301")]
51+
#[unstable(feature = "termination_trait_lib", issue = "43301")]
5552
impl<T: Termination, E: Debug> Termination for Result<T, E> {
5653
fn report(self) -> i32 {
5754
match self {
@@ -64,19 +61,19 @@ impl<T: Termination, E: Debug> Termination for Result<T, E> {
6461
}
6562
}
6663

67-
#[unstable(feature = "termination_trait", issue = "43301")]
64+
#[unstable(feature = "termination_trait_lib", issue = "43301")]
6865
impl Termination for ! {
6966
fn report(self) -> i32 { unreachable!(); }
7067
}
7168

72-
#[unstable(feature = "termination_trait", issue = "43301")]
69+
#[unstable(feature = "termination_trait_lib", issue = "43301")]
7370
impl Termination for bool {
7471
fn report(self) -> i32 {
7572
if self { exit::SUCCESS } else { exit::FAILURE }
7673
}
7774
}
7875

79-
#[unstable(feature = "termination_trait", issue = "43301")]
76+
#[unstable(feature = "termination_trait_lib", issue = "43301")]
8077
impl Termination for i32 {
8178
fn report(self) -> i32 {
8279
self

src/libsyntax/test.rs

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -746,48 +746,36 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
746746
};
747747
visible_path.extend(path);
748748

749-
// If termination feature is enabled, create a wrapper that invokes the fn
750-
// like this:
749+
// Rather than directly give the test function to the test
750+
// harness, we create a wrapper like this:
751751
//
752-
// fn wrapper() {
753-
// assert_eq!(0, real_function().report());
754-
// }
752+
// || test::assert_test_result(real_function())
755753
//
756-
// and then put a reference to `wrapper` into the test descriptor. Otherwise,
757-
// just put a direct reference to `real_function`.
754+
// this will coerce into a fn pointer that is specialized to the
755+
// actual return type of `real_function` (Typically `()`, but not always).
758756
let fn_expr = {
759-
let base_fn_expr = ecx.expr_path(ecx.path_global(span, visible_path));
760-
if cx.features.termination_trait {
761-
// ::std::Termination::assert_unit_test_successful
762-
let assert_unit_test_successful = ecx.path_global(
757+
// construct `real_function()` (this will be inserted into the overall expr)
758+
let real_function_expr = ecx.expr_path(ecx.path_global(span, visible_path));
759+
// construct path `test::assert_test_result`
760+
let assert_test_result = test_path("assert_test_result");
761+
// construct `|| {..}`
762+
ecx.lambda(
763+
span,
764+
vec![],
765+
// construct `assert_test_result(..)`
766+
ecx.expr_call(
763767
span,
768+
ecx.expr_path(assert_test_result),
764769
vec![
765-
ecx.ident_of("std"),
766-
ecx.ident_of("Termination"),
767-
ecx.ident_of("assert_unit_test_successful"),
770+
// construct `real_function()`
771+
ecx.expr_call(
772+
span,
773+
real_function_expr,
774+
vec![],
775+
)
768776
],
769-
);
770-
// || {..}
771-
ecx.lambda(
772-
span,
773-
vec![],
774-
// ::std::Termination::assert_unit_test_successful(..)
775-
ecx.expr_call(
776-
span,
777-
ecx.expr_path(assert_unit_test_successful),
778-
vec![
779-
// $base_fn_expr()
780-
ecx.expr_call(
781-
span,
782-
base_fn_expr,
783-
vec![],
784-
)
785-
],
786-
),
787-
)
788-
} else {
789-
base_fn_expr
790-
}
777+
),
778+
)
791779
};
792780

793781
let variant_name = if test.bench { "StaticBenchFn" } else { "StaticTestFn" };

src/libtest/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#![feature(set_stdio)]
4141
#![feature(panic_unwind)]
4242
#![feature(staged_api)]
43+
#![feature(termination_trait_lib)]
4344

4445
extern crate getopts;
4546
extern crate term;
@@ -69,6 +70,7 @@ use std::iter::repeat;
6970
use std::path::PathBuf;
7071
use std::sync::mpsc::{channel, Sender};
7172
use std::sync::{Arc, Mutex};
73+
use std::termination::Termination;
7274
use std::thread;
7375
use std::time::{Instant, Duration};
7476
use std::borrow::Cow;
@@ -322,6 +324,13 @@ pub fn test_main_static(tests: &[TestDescAndFn]) {
322324
test_main(&args, owned_tests, Options::new())
323325
}
324326

327+
/// Invoked when unit tests terminate. Should panic if the unit
328+
/// test is considered a failure. By default, invokes `report()`
329+
/// and checks for a `0` result.
330+
pub fn assert_test_result<T: Termination>(result: T) {
331+
assert_eq!(result.report(), 0);
332+
}
333+
325334
#[derive(Copy, Clone, Debug)]
326335
pub enum ColorConfig {
327336
AutoColor,

src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
#![feature(termination_trait)]
1111

1212
fn main() -> char {
13-
//~^ ERROR: the trait bound `char: std::Termination` is not satisfied
13+
//~^ ERROR: the trait bound `char: std::termination::Termination` is not satisfied
1414
' '
1515
}

src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212

1313
struct ReturnType {}
1414

15-
fn main() -> ReturnType { //~ ERROR `ReturnType: std::Termination` is not satisfied
15+
fn main() -> ReturnType { //~ ERROR `ReturnType: std::termination::Termination` is not satisfied
1616
ReturnType {}
1717
}

0 commit comments

Comments
 (0)