Skip to content

Conversation

@conradludgate
Copy link
Contributor

Motivation

Fixes #3431

Solution

This is horrible. We rename valueset! to valueset_all!, then we re-introduce the original valueset! with some notable changes.

The new valueset! doesn't use fields from the fieldset iterator, it instead uses FieldSet::field(...) to find the correct field. If the field isn't found, we set a fallback field that will be ignored (callsites are not equal).

@conradludgate conradludgate requested review from a team, hawkw and hds as code owners November 28, 2025 18:55
Comment on lines +2997 to +3004
// create a dummy callsite to get a bogus field.
static __CALLSITE: $crate::callsite::DefaultCallsite = $crate::callsite2! {
name: "__fake_tracing_callsite",
kind: $crate::metadata::Kind::SPAN,
target: module_path!(),
level: $crate::Level::TRACE,
fields: $crate::fieldset!("__fake_tracing_field" = "fake_tracing_value"),
};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please suggest a better way to create a fake Field. I hate this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative could be some construction based on ArrayVec, we only push the fields that are found.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than using another dep on arrayvec, we could use MaybeUninit and the relevant unsafe. Neither Field nor Option<&dyn Value> need to be dropped, which simplifies the setup.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need to be different from the original implementation before #3398?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original implementation iterates over fields in the span metadata. It doesn't construct the field name based on the actual current field given. recordall! simply never worked beyond the case of the exact same spans in the exact order.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can see that it calls $next and discards $k. So whatever is in the field name provided in recordall! is simply discarded.

$crate::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),

tracing/tracing/src/macros.rs

Lines 2982 to 2987 in c47c777

(@ { $(,)* $($out:expr),* }, $next:expr, { $k:expr } = $val:expr) => {
$crate::valueset!(
@ { $($out),*, (&$next, Some(&$val as &dyn $crate::field::Value)) },
$next,
)
};

@hds hds changed the title Fix record_all panic tracing: fix record_all panic Dec 1, 2025
@hds hds self-assigned this Dec 1, 2025
@hds hds added kind/bug Something isn't working crate/tracing Related to the `tracing` crate labels Dec 1, 2025
Copy link
Contributor

@hds hds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR!

I think it would be good to have a little more test coverage. Especially because these macros are frequent sources of unintentional breaking changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

crate/tracing Related to the `tracing` crate kind/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

record_all! panics if used with incomplete values

2 participants