diff options
| author | bors <bors@rust-lang.org> | 2018-04-24 10:44:22 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-04-24 10:44:22 +0000 |
| commit | 2a6200a5c8f19763268f531302ed7ddccf1e7204 (patch) | |
| tree | 9db4de0f9b98d38f0598ca00c1a52cad7361740a /src/libsyntax | |
| parent | 898c9f7d71f202e1e472427694347da4a91d8258 (diff) | |
| parent | 14e5e0e9c9f01e29cd1e8d7da10e85b655288b2e (diff) | |
| download | rust-2a6200a5c8f19763268f531302ed7ddccf1e7204.tar.gz rust-2a6200a5c8f19763268f531302ed7ddccf1e7204.zip | |
Auto merge of #49911 - rcoh:master, r=nikomatsakis
Don't allow #[should_panic] with non-() tests Adds (removes) support for `#[should_panic]` when the test is non-`()`
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/test.rs | 67 |
1 files changed, 40 insertions, 27 deletions
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index fd2e760e9be..325927ed832 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -320,37 +320,48 @@ fn ignored_span(cx: &TestCtxt, sp: Span) -> Span { #[derive(PartialEq)] enum HasTestSignature { Yes, - No, + No(BadTestSignature), +} + +#[derive(PartialEq)] +enum BadTestSignature { NotEvenAFunction, + WrongTypeSignature, + NoArgumentsAllowed, + ShouldPanicOnlyWithNoArgs, } fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { let has_test_attr = attr::contains_name(&i.attrs, "test"); fn has_test_signature(cx: &TestCtxt, i: &ast::Item) -> HasTestSignature { + let has_should_panic_attr = attr::contains_name(&i.attrs, "should_panic"); match i.node { ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => { // If the termination trait is active, the compiler will check that the output // type implements the `Termination` trait as `libtest` enforces that. - let output_matches = if cx.features.termination_trait_test { - true - } else { - let no_output = match decl.output { - ast::FunctionRetTy::Default(..) => true, - ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true, - _ => false - }; - - no_output && !generics.is_parameterized() + let has_output = match decl.output { + ast::FunctionRetTy::Default(..) => false, + ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => false, + _ => true }; - if decl.inputs.is_empty() && output_matches { - Yes - } else { - No + if !decl.inputs.is_empty() { + return No(BadTestSignature::NoArgumentsAllowed); + } + + match (has_output, cx.features.termination_trait_test, has_should_panic_attr) { + (true, true, true) => No(BadTestSignature::ShouldPanicOnlyWithNoArgs), + (true, true, false) => if generics.is_parameterized() { + No(BadTestSignature::WrongTypeSignature) + } else { + Yes + }, + (true, false, _) => No(BadTestSignature::WrongTypeSignature), + (false, _, _) => Yes } } - _ => NotEvenAFunction, + _ => No(BadTestSignature::NotEvenAFunction), } } @@ -358,18 +369,20 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { let diag = cx.span_diagnostic; match has_test_signature(cx, i) { Yes => true, - No => { - if cx.features.termination_trait_test { - diag.span_err(i.span, "functions used as tests can not have any arguments"); - } else { - diag.span_err(i.span, "functions used as tests must have signature fn() -> ()"); + No(cause) => { + match cause { + BadTestSignature::NotEvenAFunction => + diag.span_err(i.span, "only functions may be used as tests"), + BadTestSignature::WrongTypeSignature => + diag.span_err(i.span, + "functions used as tests must have signature fn() -> ()"), + BadTestSignature::NoArgumentsAllowed => + diag.span_err(i.span, "functions used as tests can not have any arguments"), + BadTestSignature::ShouldPanicOnlyWithNoArgs => + diag.span_err(i.span, "functions using `#[should_panic]` must return `()`"), } false - }, - NotEvenAFunction => { - diag.span_err(i.span, "only functions may be used as tests"); - false - }, + } } } else { false @@ -407,7 +420,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { // well before resolve, can't get too deep. input_cnt == 1 && output_matches } - _ => false + _ => false } } |
