diff --git a/tracing/src/macros.rs b/tracing/src/macros.rs index 9194db8e3..d82a635f1 100644 --- a/tracing/src/macros.rs +++ b/tracing/src/macros.rs @@ -2959,6 +2959,47 @@ macro_rules! valueset { ) }; + // Handle constant names + (@ { $(,)* $($out:expr),* }, $next:expr, { $k:expr } = ?$val:expr, $($rest:tt)*) => { + $crate::valueset!( + @ { $($out),*, (&$next, Some(&debug(&$val) as &dyn Value)) }, + $next, + $($rest)* + ) + }; + (@ { $(,)* $($out:expr),* }, $next:expr, { $k:expr } = %$val:expr, $($rest:tt)*) => { + $crate::valueset!( + @ { $($out),*, (&$next, Some(&display(&$val) as &dyn Value)) }, + $next, + $($rest)* + ) + }; + (@ { $(,)* $($out:expr),* }, $next:expr, { $k:expr } = $val:expr, $($rest:tt)*) => { + $crate::valueset!( + @ { $($out),*, (&$next, Some(&$val as &dyn Value)) }, + $next, + $($rest)* + ) + }; + (@ { $(,)* $($out:expr),* }, $next:expr, { $k:expr } = ?$val:expr) => { + $crate::valueset!( + @ { $($out),*, (&$next, Some(&debug(&$val) as &dyn Value)) }, + $next, + ) + }; + (@ { $(,)* $($out:expr),* }, $next:expr, { $k:expr } = %$val:expr) => { + $crate::valueset!( + @ { $($out),*, (&$next, Some(&display(&$val) as &dyn Value)) }, + $next, + ) + }; + (@ { $(,)* $($out:expr),* }, $next:expr, { $k:expr } = $val:expr) => { + $crate::valueset!( + @ { $($out),*, (&$next, Some(&$val as &dyn Value)) }, + $next, + ) + }; + // Remainder is unparsable, but exists --- must be format args! (@ { $(,)* $($out:expr),* }, $next:expr, $($rest:tt)+) => { $crate::valueset!(@ { (&$next, $crate::__macro_support::Option::Some(&$crate::__macro_support::format_args!($($rest)+) as &dyn Value)), $($out),* }, $next, ) diff --git a/tracing/tests/event.rs b/tracing/tests/event.rs index d8a98a616..857045e02 100644 --- a/tracing/tests/event.rs +++ b/tracing/tests/event.rs @@ -525,3 +525,45 @@ fn string_field() { handle.assert_finished(); } + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn constant_field_name() { + let expect_event = || { + expect::event().with_fields( + expect::field("foo") + .with_value(&"bar") + .and(expect::field("constant string").with_value(&"also works")) + .and(expect::field("foo.bar").with_value(&"baz")) + .and(expect::field("message").with_value(&debug(format_args!("quux")))) + .only(), + ) + }; + let (subscriber, handle) = subscriber::mock() + .event(expect_event()) + .event(expect_event()) + .only() + .run_with_handle(); + + with_default(subscriber, || { + const FOO: &str = "foo"; + tracing::event!( + Level::INFO, + { std::convert::identity(FOO) } = "bar", + { "constant string" } = "also works", + foo.bar = "baz", + "quux" + ); + tracing::event!( + Level::INFO, + { + { std::convert::identity(FOO) } = "bar", + { "constant string" } = "also works", + foo.bar = "baz", + }, + "quux" + ); + }); + + handle.assert_finished(); +}