Skip to content

Commit

Permalink
tracing: fix macro hygiene for concat! (tokio-rs#1918)
Browse files Browse the repository at this point in the history
Re-application of changes made in tokio-rs#1842 which were lost in f1cf1f1

Integration tests added for regression.

---

## Motivation

In my library I define a `macro_rules! concat` macro, i.e.
[`callbag::concat`](https://docs.rs/callbag/latest/callbag/macro.concat.html).

When I try to call `tracing::info!(...)`, I get error output such as
this:

<details>
<summary>error output</summary>

<!-- leave a blank line above -->
```
> RUSTFLAGS='-Z macro-backtrace' cargo +nightly clippy --features trace
    Checking callbag v0.14.0 (/home/teohhanhui/projects/teohhanhui/callbag-rs)
error[E0308]: mismatched types
  --> src/concat.rs:89:9
   |
89 |         info!("from sink: {message:?}");
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found `u32`

error[E0277]: the trait bound `std::sync::Arc<core::Callbag<never::Never, _>>: std::convert::From<&str>` is not satisfied
    --> src/concat.rs:58:9
     |
56   | / macro_rules! concat {
57   | |     ($($s:expr),* $(,)?) => {
58   | |         $crate::concat(::std::vec![$($s),*].into_boxed_slice())
     | |         ^^^^^^^^^^^^^^ the trait `std::convert::From<&str>` is not implemented for `std::sync::Arc<core::Callbag<never::Never, _>>`
59   | |     };
60   | | }
     | |_- in this expansion of `concat!` (tokio-rs#5)
...
89   |           info!("from sink: {message:?}");
     |           ------------------------------- in this macro invocation (tokio-rs#1)
     |
    ::: src/utils/tracing.rs:47:1
     |
47   | / macro_rules! info {
48   | |     ($($arg:tt)+) => {
49   | |         ::cfg_if::cfg_if! {
50   | |             if #[cfg(feature = "trace")] {
51   | |                 ::tracing::info!($($arg)+)
     | |                 -------------------------- in this macro invocation (tokio-rs#2)
...    |
54   | |     };
55   | | }
     | |_- in this expansion of `info!` (tokio-rs#1)
     |
    ::: /home/teohhanhui/.cargo/registry/src/gh.neting.cc-1ecc6299db9ec823/tracing-0.1.29/src/macros.rs:586:1
     |
586  |   macro_rules! event {
     |  _-
     | |_|
     | |
587  | |     (target: $target:expr, parent: $parent:expr, $lvl:expr, { $($fields:tt)* } )=> (
588  | |         $crate::__tracing_log!(
589  | |             target: $target,
...    |
644  |                   name: concat!(
     |  _______________________-
645  |                       "event ",
646  |                       file!(),
647  |                       ":",
648  |                       line!()
649  | |                 ),
     | |_________________- in this macro invocation (tokio-rs#5)
...
667  | /         $crate::event!(
668  |               target: $target,
669  |               $lvl,
670  |               { message = format_args!($($arg)+), $($fields)* }
671  | |         )
     | |_________- in this macro invocation (tokio-rs#4)
...
791  | |     );
792  | | }
     | | -
     | |_|
     | |_in this expansion of `$crate::event!` (tokio-rs#3)
     |   in this expansion of `$crate::event!` (tokio-rs#4)
...
1229 | / macro_rules! info {
1230 |        (target: $target:expr, parent: $parent:expr, { $($field:tt)* }, $($arg:tt)* ) => (
1231 |           $crate::event!(target: $target, parent: $parent, $crate::Level::INFO, { $($field)* }, $($arg)*)
1232 |       );
...
1398 | /         $crate::event!(
1399 | |             target: module_path!(),
1400 | |             $crate::Level::INFO,
1401 | |             {},
1402 | |             $($arg)+
1403 | |         )
     | |_________- in this macro invocation (tokio-rs#3)
1404 |       );
1405 | | }
     | |_- in this expansion of `::tracing::info!` (tokio-rs#2)
     |
     = help: the following implementations were found:
               <std::sync::Arc<B> as std::convert::From<std::borrow::Cow<'a, B>>>
               <std::sync::Arc<T> as std::convert::From<T>>
               <std::sync::Arc<T> as std::convert::From<std::boxed::Box<T>>>
               <std::sync::Arc<[T]> as std::convert::From<&[T]>>
             and 9 others
     = note: required because of the requirements on the impl of `std::convert::Into<std::sync::Arc<core::Callbag<never::Never, _>>>` for `&str`
note: required by a bound in `concat::concat`
    --> src/concat.rs:81:8
     |
72   | pub fn concat<
     |        ------ required by a bound in this
...
81   |     S: Into<Arc<Source<T>>> + Send + Sync,
     |        ^^^^^^^^^^^^^^^^^^^^ required by this bound in `concat::concat`

error[E0308]: mismatched types
    --> src/concat.rs:58:9
     |
56   | / macro_rules! concat {
57   | |     ($($s:expr),* $(,)?) => {
58   | |         $crate::concat(::std::vec![$($s),*].into_boxed_slice())
     | |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found struct `core::Callbag`
59   | |     };
60   | | }
     | |_- in this expansion of `concat!` (tokio-rs#5)
...
89   |           info!("from sink: {message:?}");
     |           ------------------------------- in this macro invocation (tokio-rs#1)
     |
    ::: src/utils/tracing.rs:47:1
     |
47   | / macro_rules! info {
48   | |     ($($arg:tt)+) => {
49   | |         ::cfg_if::cfg_if! {
50   | |             if #[cfg(feature = "trace")] {
51   | |                 ::tracing::info!($($arg)+)
     | |                 -------------------------- in this macro invocation (tokio-rs#2)
...    |
54   | |     };
55   | | }
     | |_- in this expansion of `info!` (tokio-rs#1)
     |
    ::: /home/teohhanhui/.cargo/registry/src/gh.neting.cc-1ecc6299db9ec823/tracing-0.1.29/src/macros.rs:586:1
     |
586  |   macro_rules! event {
     |  _-
     | |_|
     | |
587  | |     (target: $target:expr, parent: $parent:expr, $lvl:expr, { $($fields:tt)* } )=> (
588  | |         $crate::__tracing_log!(
589  | |             target: $target,
...    |
644  |                   name: concat!(
     |  _______________________-
645  |                       "event ",
646  |                       file!(),
647  |                       ":",
648  |                       line!()
649  | |                 ),
     | |_________________- in this macro invocation (tokio-rs#5)
...
667  | /         $crate::event!(
668  |               target: $target,
669  |               $lvl,
670  |               { message = format_args!($($arg)+), $($fields)* }
671  | |         )
     | |_________- in this macro invocation (tokio-rs#4)
...
791  | |     );
792  | | }
     | | -
     | |_|
     | |_in this expansion of `$crate::event!` (tokio-rs#3)
     |   in this expansion of `$crate::event!` (tokio-rs#4)
...
1229 | / macro_rules! info {
1230 |        (target: $target:expr, parent: $parent:expr, { $($field:tt)* }, $($arg:tt)* ) => (
1231 |           $crate::event!(target: $target, parent: $parent, $crate::Level::INFO, { $($field)* }, $($arg)*)
1232 |       );
...
1398 | /         $crate::event!(
1399 | |             target: module_path!(),
1400 | |             $crate::Level::INFO,
1401 | |             {},
1402 | |             $($arg)+
1403 | |         )
     | |_________- in this macro invocation (tokio-rs#3)
1404 |       );
1405 | | }
     | |_- in this expansion of `::tracing::info!` (tokio-rs#2)
     |
     = note: expected reference `&'static str`
                   found struct `core::Callbag<never::Never, _>`

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `callbag` due to 3 previous errors
```
</details>

This is because of my `concat` macro being in scope.

## Solution

Change all the `tracing` macros to use the re-export of `core::concat!`
in the `__macro_support` module, rather than using an un-namespaced
`concat!`. The re-export ensures that everything still works even in a
crate that redefines the `core` name to something else.
  • Loading branch information
teohhanhui authored and kaffarell committed May 22, 2024
1 parent c9594ee commit 01f0102
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
24 changes: 24 additions & 0 deletions tracing/tests/macros_incompatible_concat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use tracing::{enabled, event, span, Level};

#[macro_export]
macro_rules! concat {
() => {};
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn span() {
span!(Level::DEBUG, "foo");
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn event() {
event!(Level::DEBUG, "foo");
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn enabled() {
enabled!(Level::DEBUG);
}
21 changes: 21 additions & 0 deletions tracing/tests/macros_redefined_core.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
extern crate self as core;

use tracing::{enabled, event, span, Level};

#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn span() {
span!(Level::DEBUG, "foo");
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn event() {
event!(Level::DEBUG, "foo");
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn enabled() {
enabled!(Level::DEBUG);
}

0 comments on commit 01f0102

Please sign in to comment.