diff --git a/tracing-attributes/src/lib.rs b/tracing-attributes/src/lib.rs index dd692512ff..b07415ef62 100644 --- a/tracing-attributes/src/lib.rs +++ b/tracing-attributes/src/lib.rs @@ -82,7 +82,7 @@ extern crate proc_macro; use proc_macro2::TokenStream; -use quote::ToTokens; +use quote::{quote, ToTokens}; use syn::parse::{Parse, ParseStream}; use syn::{Attribute, ItemFn, Signature, Visibility}; @@ -535,6 +535,14 @@ mod expand; /// } /// ``` /// +/// `const fn` cannot be instrumented, and will result in a compilation failure: +/// +/// ```compile_fail +/// # use tracing_attributes::instrument; +/// #[instrument] +/// const fn my_const_function() {} +/// ``` +/// /// [span]: https://docs.rs/tracing/latest/tracing/span/index.html /// [name]: https://docs.rs/tracing/latest/tracing/struct.Metadata.html#method.name /// [target]: https://docs.rs/tracing/latest/tracing/struct.Metadata.html#method.target @@ -585,6 +593,13 @@ fn instrument_precise( let input = syn::parse::(item)?; let instrumented_function_name = input.sig.ident.to_string(); + if input.sig.constness.is_some() { + return Ok(quote! { + compile_error!("the `#[instrument]` attribute may not be used with `const fn`s") + } + .into()); + } + // check for async_trait-like patterns in the block, and instrument // the future instead of the wrapper if let Some(async_like) = expand::AsyncInfo::from_fn(&input) { diff --git a/tracing-attributes/tests/ui.rs b/tracing-attributes/tests/ui.rs index f11cc019eb..73d7fdcef8 100644 --- a/tracing-attributes/tests/ui.rs +++ b/tracing-attributes/tests/ui.rs @@ -5,3 +5,10 @@ fn async_instrument() { let t = trybuild::TestCases::new(); t.compile_fail("tests/ui/async_instrument.rs"); } + +#[rustversion::stable] +#[test] +fn const_instrument() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/const_instrument.rs"); +} diff --git a/tracing-attributes/tests/ui/const_instrument.rs b/tracing-attributes/tests/ui/const_instrument.rs new file mode 100644 index 0000000000..a251e8f66b --- /dev/null +++ b/tracing-attributes/tests/ui/const_instrument.rs @@ -0,0 +1,8 @@ +#![allow(unreachable_code)] + +#[tracing::instrument] +const fn unit() { + "" +} + +fn main() {} diff --git a/tracing-attributes/tests/ui/const_instrument.stderr b/tracing-attributes/tests/ui/const_instrument.stderr new file mode 100644 index 0000000000..e76d4acad9 --- /dev/null +++ b/tracing-attributes/tests/ui/const_instrument.stderr @@ -0,0 +1,15 @@ +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> tests/ui/const_instrument.rs:3:1 + | +3 | #[tracing::instrument] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `tracing::instrument` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: the `#[instrument]` attribute may not be used with `const fn`s + --> tests/ui/const_instrument.rs:3:1 + | +3 | #[tracing::instrument] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `tracing::instrument` (in Nightly builds, run with -Z macro-backtrace for more info)