Skip to content

Commit 58accc6

Browse files
attributes: add compile error on const fn instrumentation (#2418)
## Motivation The `#[instrument]` macro cannot be used on `const fn`s, because the generated code will perform runtime tracing behavior. However, when adding the attribute to a `const fn`, the compiler errors generated currently are somewhat unclear (see #2414). It would be better if we generated a less verbose error that simply states that `#[instrument]` is not supported on `const fn`s. ## Solution This branch changes the `#[instrument]` macro to detect when the annotated function is a `const fn`, and emit a simpler, more descritpive error message. The new error simply states that the `#[instrument]` attribute cannot be used on `const fn`s, and should be much less confusing to the user. Fixes #2414
1 parent 7c39d4f commit 58accc6

File tree

4 files changed

+46
-1
lines changed

4 files changed

+46
-1
lines changed

tracing-attributes/src/lib.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
)]
8080

8181
use proc_macro2::TokenStream;
82-
use quote::ToTokens;
82+
use quote::{quote, ToTokens};
8383
use syn::parse::{Parse, ParseStream};
8484
use syn::{Attribute, ItemFn, Signature, Visibility};
8585

@@ -342,6 +342,14 @@ mod expand;
342342
/// }
343343
/// ```
344344
///
345+
/// `const fn` cannot be instrumented, and will result in a compilation failure:
346+
///
347+
/// ```compile_fail
348+
/// # use tracing_attributes::instrument;
349+
/// #[instrument]
350+
/// const fn my_const_function() {}
351+
/// ```
352+
///
345353
/// [span]: https://docs.rs/tracing/latest/tracing/span/index.html
346354
/// [`follows_from`]: https://docs.rs/tracing/latest/tracing/struct.Span.html#method.follows_from
347355
/// [`tracing`]: https://github.com/tokio-rs/tracing
@@ -385,6 +393,13 @@ fn instrument_precise(
385393
let input = syn::parse::<ItemFn>(item)?;
386394
let instrumented_function_name = input.sig.ident.to_string();
387395

396+
if input.sig.constness.is_some() {
397+
return Ok(quote! {
398+
compile_error!("the `#[instrument]` attribute may not be used with `const fn`s")
399+
}
400+
.into());
401+
}
402+
388403
// check for async_trait-like patterns in the block, and instrument
389404
// the future instead of the wrapper
390405
if let Some(async_like) = expand::AsyncInfo::from_fn(&input) {

tracing-attributes/tests/ui.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,10 @@ fn async_instrument() {
55
let t = trybuild::TestCases::new();
66
t.compile_fail("tests/ui/async_instrument.rs");
77
}
8+
9+
#[rustversion::stable]
10+
#[test]
11+
fn const_instrument() {
12+
let t = trybuild::TestCases::new();
13+
t.compile_fail("tests/ui/const_instrument.rs");
14+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![allow(unreachable_code)]
2+
3+
#[tracing::instrument]
4+
const fn unit() {
5+
""
6+
}
7+
8+
fn main() {}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: macros that expand to items must be delimited with braces or followed by a semicolon
2+
--> tests/ui/const_instrument.rs:3:1
3+
|
4+
3 | #[tracing::instrument]
5+
| ^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: this error originates in the attribute macro `tracing::instrument` (in Nightly builds, run with -Z macro-backtrace for more info)
8+
9+
error: the `#[instrument]` attribute may not be used with `const fn`s
10+
--> tests/ui/const_instrument.rs:3:1
11+
|
12+
3 | #[tracing::instrument]
13+
| ^^^^^^^^^^^^^^^^^^^^^^
14+
|
15+
= note: this error originates in the attribute macro `tracing::instrument` (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)