Macro_rules!: is it possible to "bubble" error locations from it?

I'm writing a tests for a library and I want to write a big portion of similar tests, so I'm using macro:

mod tests {
  macro_rules! check {
    ($buf:expr) => {
      // big stuff
    }
  }

  mod owned {
    check!(&mut Vec::new());
  }

  mod borrowed {
    check!(());
  }
}

But there is a problem: when tests fails, error location pointed to the check!() invocation site, not to the actual place where I check conditions. Is there any way to mark check!() macro that locations "bubble" from it? Conteptually this is something reverse to a #[track_caller] attribute

The span of the macro output contains the full expansion chain. By default rustc only shows the span corresponding to the macro invocation site, but you can use -Zmacro-backtrace=yes on nightly to show the location inside the macro too.

1 Like

Yes, I know, that is temporary solution that I use now. Problem with that in that it's too verbose when you have even several tests failed. I'm looking for, maybe there is a more elegant solution?

You could try to factor out most of the stuff within helper functions, so that the backtraces already can be used, and then try to use a layer of generics in between the macros and the tested code.

In your case, thus, ::generic-tests may be a nice way to XY your problem:

Thanks! It seems that this crate should solve my problem in general, but but implementation has encountered some difficulties.

Anyway, I mark this as answer because direction seems right.

1 Like

After all I almost achieved the goal, but right now Compilation failed when test inside of submodule · Issue #5 · mzabaluev/generic-tests · GitHub prevents me from just adding few lines to switch from macro_rules-based approach to the generic-tests approach. When it will be solved, I'll post a full solution

Yeah, I don't thing the generic_tests macro is yet able to handle nested modules; but it's good that you submitted the issue, since it could be made to :slightly_smiling_face:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.