Change:
Edit: outstanding work is to change the span from pointing at the function body to point at the return type. adds a test for the case where a unit test returns a value that does not implement . The message currently talks about and has an ugly multi-line span: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
As long as we have the method signature around when we emit E0277, it has a field with the span for the return type, which should be used for this instead, but this will probably require some special casing this in that (already quite hairy) diagnostic code. Extending could be possible, but I would advice against doing so to avoid turning that attribute into a bigger monster than it already is.
Chiming in that this confused me as I was preparing for a Rust training session, where I expect it would confuse the students even more. Specifically, this should not talk about at all as it's plausible to cause people to look in the wrong spot.
CC
Just started learning Rust and came across this error while writing some tests- I absolutely agree "ungreat" is perfect word choice.
It could get even more confusing when : Rust 1.64
This issue is now (mostly) fixed on nightly by and should be closed I think. The error message is now correct but the span is still “ugly”. I've overlooked this issue and only closed its duplicate, namely .
Actually, let's keep this open only for the span change :)
Just wrap the return type with a struct and implement the Termination trait for that wrapper struct example
Note that this GitHub issue is about the subpar error message given by the compiler which should be fixed and not about potential solutions for user code when facing this message. claim

Discussion:
}; // Note: non-associated fn items are already handled by `expand_test_or_bench` <del> if !matches!(item.kind, ast::ItemKind::Fn(_)) { </del> <ins> let ast::ItemKind::Fn(fn_) = &item.kind else { </ins> let diag = &cx.sess.parse_sess.span_diagnostic; let msg = "the `#[test]` attribute may only be used on a non-associated function"; let mut err = match item.kind {

.emit(); return vec![Annotatable::Item(item)]; <del> } </del> <ins> }; </ins> // has_*_signature will report any errors in the type so compilation // will fail. We shouldn't try to expand in this case because the errors

return vec![Annotatable::Item(item)]; } <del> let (sp, attr_sp) = (cx.with_def_site_ctxt(item.span), cx.with_def_site_ctxt(attr_sp)); </del> <ins> let sp = cx.with_def_site_ctxt(item.span); let ret_ty_sp = cx.with_def_site_ctxt(fn_.sig.decl.output.span()); let attr_sp = cx.with_def_site_ctxt(attr_sp); </ins> let test_id = Ident::new(sym::test, attr_sp); // creates test::$name <del> let test_path = |name| cx.path(sp, vec![test_id, Ident::from_str_and_span(name, sp)]); </del> <ins> let test_path = |name| cx.path(ret_ty_sp, vec![test_id, Ident::from_str_and_span(name, sp)]); </ins> // creates test::ShouldPanic::$name let should_panic_path = |name| {

vec![ // super::$test_fn(b) cx.expr_call( <del> sp, </del> <ins> ret_ty_sp, </ins> cx.expr_path(cx.path(sp, vec![item.ident])), vec![cx.expr_ident(sp, b)], ),

cx.expr_path(test_path("assert_test_result")), vec![ // $test_fn() <del> cx.expr_call(sp, cx.expr_path(cx.path(sp, vec![item.ident])), vec![]), // ) </del> <ins> cx.expr_call( ret_ty_sp, cx.expr_path(cx.path(sp, vec![item.ident])), vec![], ), // ) </ins> ], ), // } ), // )

error[E0277]: the trait bound `f32: Termination` is not satisfied <del> --> $DIR/termination-trait-test-wrong-type.rs:6:1 </del> <ins> --> $DIR/termination-trait-test-wrong-type.rs:6:31 </ins> | <del> LL |   #[test] |   ------- in this procedural macro expansion LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> { LL | |     "0".parse() LL | | } | |_^ the trait `Termination` is not implemented for `f32` </del> <ins> LL | #[test] | ------- in this procedural macro expansion LL | fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> { |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Termination` is not implemented for `f32` </ins> | = note: required for `Result<f32, ParseFloatError>` to implement `Termination` note: required by a bound in `assert_test_result`