Skip to content

Commit 22725de

Browse files
authored
Rollup merge of rust-lang#103445 - fmease:fix-50291, r=estebank
`#[test]`: Point at return type if `Termination` bound is unsatisfied Together with rust-lang#103142 (already merged) this fully fixes rust-lang#50291. I don't consider my current solution of changing a few spans “here and there” very clean since the failed obligation is a `FunctionArgumentObligation` and we point at a type instead of a function argument. If you agree with me on this point, I can offer to keep the spans of the existing nodes and instead inject `let _: AssertRetTyIsTermination<$ret_ty>;` (type to be defined in `libtest`) similar to `AssertParamIsEq` etc. used by some built-in derive-macros. I haven't tried that approach yet though and cannot promise that it would actually work out or be “cleaner” for that matter. ```@rustbot``` label A-libtest A-diagnostics r? ```@estebank```
2 parents ebddca4 + 449a440 commit 22725de

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

compiler/rustc_builtin_macros/src/test.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ pub fn expand_test_or_bench(
112112
};
113113

114114
// Note: non-associated fn items are already handled by `expand_test_or_bench`
115-
if !matches!(item.kind, ast::ItemKind::Fn(_)) {
115+
let ast::ItemKind::Fn(fn_) = &item.kind else {
116116
let diag = &cx.sess.parse_sess.span_diagnostic;
117117
let msg = "the `#[test]` attribute may only be used on a non-associated function";
118118
let mut err = match item.kind {
@@ -130,7 +130,7 @@ pub fn expand_test_or_bench(
130130
.emit();
131131

132132
return vec![Annotatable::Item(item)];
133-
}
133+
};
134134

135135
// has_*_signature will report any errors in the type so compilation
136136
// will fail. We shouldn't try to expand in this case because the errors
@@ -141,12 +141,14 @@ pub fn expand_test_or_bench(
141141
return vec![Annotatable::Item(item)];
142142
}
143143

144-
let (sp, attr_sp) = (cx.with_def_site_ctxt(item.span), cx.with_def_site_ctxt(attr_sp));
144+
let sp = cx.with_def_site_ctxt(item.span);
145+
let ret_ty_sp = cx.with_def_site_ctxt(fn_.sig.decl.output.span());
146+
let attr_sp = cx.with_def_site_ctxt(attr_sp);
145147

146148
let test_id = Ident::new(sym::test, attr_sp);
147149

148150
// creates test::$name
149-
let test_path = |name| cx.path(sp, vec![test_id, Ident::from_str_and_span(name, sp)]);
151+
let test_path = |name| cx.path(ret_ty_sp, vec![test_id, Ident::from_str_and_span(name, sp)]);
150152

151153
// creates test::ShouldPanic::$name
152154
let should_panic_path = |name| {
@@ -192,7 +194,7 @@ pub fn expand_test_or_bench(
192194
vec![
193195
// super::$test_fn(b)
194196
cx.expr_call(
195-
sp,
197+
ret_ty_sp,
196198
cx.expr_path(cx.path(sp, vec![item.ident])),
197199
vec![cx.expr_ident(sp, b)],
198200
),
@@ -216,7 +218,11 @@ pub fn expand_test_or_bench(
216218
cx.expr_path(test_path("assert_test_result")),
217219
vec![
218220
// $test_fn()
219-
cx.expr_call(sp, cx.expr_path(cx.path(sp, vec![item.ident])), vec![]), // )
221+
cx.expr_call(
222+
ret_ty_sp,
223+
cx.expr_path(cx.path(sp, vec![item.ident])),
224+
vec![],
225+
), // )
220226
],
221227
), // }
222228
), // )

src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
error[E0277]: the trait bound `f32: Termination` is not satisfied
2-
--> $DIR/termination-trait-test-wrong-type.rs:6:1
2+
--> $DIR/termination-trait-test-wrong-type.rs:6:31
33
|
4-
LL | #[test]
5-
| ------- in this procedural macro expansion
6-
LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
7-
LL | | "0".parse()
8-
LL | | }
9-
| |_^ the trait `Termination` is not implemented for `f32`
4+
LL | #[test]
5+
| ------- in this procedural macro expansion
6+
LL | fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Termination` is not implemented for `f32`
108
|
119
= note: required for `Result<f32, ParseFloatError>` to implement `Termination`
1210
note: required by a bound in `assert_test_result`

0 commit comments

Comments
 (0)