From 8fbdb1cd6baf83ba9bc930683cbd1b2980252558 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 13 Jul 2022 19:27:16 -0400 Subject: [PATCH] tracing: allow owned values and fat pointers in `Span::record` (#2212) Previously, using `record("x", "y")` would give an error: ``` error[E0277]: the size for values of type `str` cannot be known at compilation time --> src/main.rs:3:22 | 243 | span.record("x", "y"); | ^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` note: required by a bound in `Span::record` --> /home/jnelson/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/tracing-0.1.32/src/span.rs:1184:30 | 1184 | pub fn record(&self, field: &Q, value: &V) -> &Self | ^ required by this bound in `Span::record` ``` Now it works fine, as tested by the doc-example. This doesn't break any existing code, because there's a generic `impl Value for &T`: https://docs.rs/tracing/0.1.35/tracing/trait.Value.html#impl-Value-for-%26%27a%20T Co-authored-by: Eliza Weisman --- tracing/src/span.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tracing/src/span.rs b/tracing/src/span.rs index 21358eb276..58822f4d9b 100644 --- a/tracing/src/span.rs +++ b/tracing/src/span.rs @@ -1136,7 +1136,7 @@ impl Span { /// /// // Now, record a value for parting as well. /// // (note that the field name is passed as a string slice) - /// span.record("parting", &"goodbye world!"); + /// span.record("parting", "goodbye world!"); /// ``` /// However, it may also be used to record a _new_ value for a field whose /// value was already recorded: @@ -1154,7 +1154,7 @@ impl Span { /// } /// Err(_) => { /// // Things are no longer okay! - /// span.record("is_okay", &false); + /// span.record("is_okay", false); /// } /// } /// ``` @@ -1181,17 +1181,17 @@ impl Span { /// // Now, you try to record a value for a new field, `new_field`, which was not /// // declared as `Empty` or populated when you created `span`. /// // You won't get any error, but the assignment will have no effect! - /// span.record("new_field", &"interesting_value_you_really_need"); + /// span.record("new_field", "interesting_value_you_really_need"); /// /// // Instead, all fields that may be recorded after span creation should be declared up front, /// // using field::Empty when a value is not known, as we did for `parting`. /// // This `record` call will indeed replace field::Empty with "you will be remembered". - /// span.record("parting", &"you will be remembered"); + /// span.record("parting", "you will be remembered"); /// ``` /// /// [`field::Empty`]: super::field::Empty /// [`Metadata`]: super::Metadata - pub fn record(&self, field: &Q, value: &V) -> &Self + pub fn record(&self, field: &Q, value: V) -> &Self where Q: field::AsField, V: field::Value, @@ -1201,7 +1201,7 @@ impl Span { self.record_all( &meta .fields() - .value_set(&[(&field, Some(value as &dyn field::Value))]), + .value_set(&[(&field, Some(&value as &dyn field::Value))]), ); } } @@ -1614,4 +1614,10 @@ mod test { impl AssertSync for Span {} impl AssertSync for Entered<'_> {} impl AssertSync for EnteredSpan {} + + #[test] + fn test_record_backwards_compat() { + Span::current().record("some-key", &"some text"); + Span::current().record("some-key", &false); + } }