@@ -320,56 +320,69 @@ fn ignored_span(cx: &TestCtxt, sp: Span) -> Span {
320
320
#[ derive( PartialEq ) ]
321
321
enum HasTestSignature {
322
322
Yes ,
323
- No ,
323
+ No ( BadTestSignature ) ,
324
+ }
325
+
326
+ #[ derive( PartialEq ) ]
327
+ enum BadTestSignature {
324
328
NotEvenAFunction ,
329
+ WrongTypeSignature ,
330
+ NoArgumentsAllowed ,
331
+ ShouldPanicOnlyWithNoArgs
325
332
}
326
333
327
334
fn is_test_fn ( cx : & TestCtxt , i : & ast:: Item ) -> bool {
328
335
let has_test_attr = attr:: contains_name ( & i. attrs , "test" ) ;
329
336
330
337
fn has_test_signature ( cx : & TestCtxt , i : & ast:: Item ) -> HasTestSignature {
338
+ let has_should_panic_attr = attr:: contains_name ( & i. attrs , "should_panic" ) ;
331
339
match i. node {
332
340
ast:: ItemKind :: Fn ( ref decl, _, _, _, ref generics, _) => {
333
341
// If the termination trait is active, the compiler will check that the output
334
342
// type implements the `Termination` trait as `libtest` enforces that.
335
- let output_matches = if cx. features . termination_trait_test {
336
- true
337
- } else {
338
- let no_output = match decl. output {
339
- ast:: FunctionRetTy :: Default ( ..) => true ,
340
- ast:: FunctionRetTy :: Ty ( ref t) if t. node == ast:: TyKind :: Tup ( vec ! [ ] ) => true ,
341
- _ => false
342
- } ;
343
-
344
- no_output && !generics. is_parameterized ( )
343
+ let has_output = match decl. output {
344
+ ast:: FunctionRetTy :: Default ( ..) => false ,
345
+ ast:: FunctionRetTy :: Ty ( ref t) if t. node == ast:: TyKind :: Tup ( vec ! [ ] ) => false ,
346
+ _ => true
345
347
} ;
346
348
347
- if decl. inputs . is_empty ( ) && output_matches {
348
- Yes
349
- } else {
350
- No
349
+ if !decl. inputs . is_empty ( ) {
350
+ return No ( BadTestSignature :: NoArgumentsAllowed )
351
+ }
352
+
353
+ match ( has_output, cx. features . termination_trait_test , has_should_panic_attr) {
354
+ ( true , true , true ) => No ( BadTestSignature :: ShouldPanicOnlyWithNoArgs ) ,
355
+ ( true , true , false ) => if generics. is_parameterized ( ) {
356
+ No ( BadTestSignature :: WrongTypeSignature )
357
+ } else {
358
+ Yes
359
+ } ,
360
+ ( true , false , _) => No ( BadTestSignature :: WrongTypeSignature ) ,
361
+ ( false , _, _) => Yes
362
+
351
363
}
352
364
}
353
- _ => NotEvenAFunction ,
365
+ _ => No ( BadTestSignature :: NotEvenAFunction ) ,
354
366
}
355
367
}
356
368
357
369
let has_test_signature = if has_test_attr {
358
370
let diag = cx. span_diagnostic ;
359
371
match has_test_signature ( cx, i) {
360
372
Yes => true ,
361
- No => {
362
- if cx. features . termination_trait_test {
363
- diag. span_err ( i. span , "functions used as tests can not have any arguments" ) ;
364
- } else {
365
- diag. span_err ( i. span , "functions used as tests must have signature fn() -> ()" ) ;
373
+ No ( cause) => {
374
+ match cause {
375
+ BadTestSignature :: NotEvenAFunction =>
376
+ diag. span_err ( i. span , "only functions may be used as tests" ) ,
377
+ BadTestSignature :: WrongTypeSignature =>
378
+ diag. span_err ( i. span , "functions used as tests must have signature fn() -> ()" ) ,
379
+ BadTestSignature :: NoArgumentsAllowed =>
380
+ diag. span_err ( i. span , "functions used as tests can not have any arguments" ) ,
381
+ BadTestSignature :: ShouldPanicOnlyWithNoArgs =>
382
+ diag. span_err ( i. span , "test functions returning Result<> must not use #[should_panic]" ) ,
366
383
}
367
384
false
368
- } ,
369
- NotEvenAFunction => {
370
- diag. span_err ( i. span , "only functions may be used as tests" ) ;
371
- false
372
- } ,
385
+ }
373
386
}
374
387
} else {
375
388
false
0 commit comments