Skip to content

Add instrument_fn attribute#157681

Open
pmur wants to merge 1 commit into
rust-lang:mainfrom
pmur:murp/add-instrument_fn-attr
Open

Add instrument_fn attribute#157681
pmur wants to merge 1 commit into
rust-lang:mainfrom
pmur:murp/add-instrument_fn-attr

Conversation

@pmur

@pmur pmur commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

This attribute enables or disables function instrumentation when using -Zinstrument-xray or -Zinstrument-mcount.

It supports the following usage:

#[instrument_fn = "on|off"]

For XRay, "on" is equivalent to always instrument, and "off" is equivalent to never instrumenting.

For mcount, "on" has no effect. "off" disables instrumentation of the function.

This is tracked by #157081, and related to the pending rfc rust-lang/rfcs#3917, and earlier as part mcp rust-lang/compiler-team#561

@rustbot

rustbot commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Some changes occurred in compiler/rustc_passes/src/check_attr.rs

cc @jdonszelmann, @JonathanBrouwer

Some changes occurred in compiler/rustc_hir/src/attrs

cc @jdonszelmann, @JonathanBrouwer

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

@rustbot rustbot added A-attributes Area: Attributes (`#[…]`, `#![…]`) A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 9, 2026
@rustbot

rustbot commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

r? @oli-obk

rustbot has assigned @oli-obk.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 73 candidates
  • Random selection from 18 candidates

@rust-log-analyzer

This comment has been minimized.

@pmur pmur force-pushed the murp/add-instrument_fn-attr branch from 8c64d48 to 8d7140c Compare June 9, 2026 20:38
@rustbot

rustbot commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rust-log-analyzer

This comment has been minimized.

This attribute enables or disables function instrumentation
when using `-Zinstrument-xray` or `-Zinstrument-mcount`.

It supports the following usage:

`#[instrument_fn = "on|off"]`

For XRay, "on" is equivalent to always instrument, and "off" is
equivalent to never instrumenting.

For mcount, "on" has no effect. "off" disables instrumentation
of the function.
@pmur pmur force-pushed the murp/add-instrument_fn-attr branch from 8d7140c to 42c43f0 Compare June 9, 2026 21:02
@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
To only update this specific test, also pass `--test-args attributes/instrument_fn.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/attributes/instrument_fn.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/attributes/instrument_fn" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
--- stderr -------------------------------
error[E0658]: attributes on expressions are experimental
##[error]  --> /checkout/tests/ui/attributes/instrument_fn.rs:13:9
   |
LL |         #[instrument_fn = "off"] //~ ERROR attribute cannot be used on
   |         ^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: `#[instrument_fn]` attribute cannot be used on structs
##[error]  --> /checkout/tests/ui/attributes/instrument_fn.rs:3:1
   |
LL | #[instrument_fn = "on"] //~ ERROR attribute cannot be used on
   | ^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: `#[instrument_fn]` can only be applied to functions

error: `#[instrument_fn]` attribute cannot be used on modules
##[error]  --> /checkout/tests/ui/attributes/instrument_fn.rs:6:1
   |
LL | #[instrument_fn = "on"] //~ ERROR attribute cannot be used on
   | ^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: `#[instrument_fn]` can only be applied to functions

error: `#[instrument_fn]` attribute cannot be used on inherent impl blocks
##[error]  --> /checkout/tests/ui/attributes/instrument_fn.rs:9:1
   |
LL | #[instrument_fn = "on"] //~ ERROR attribute cannot be used on
   | ^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: `#[instrument_fn]` can only be applied to functions

error: `#[instrument_fn]` attribute cannot be used on expressions
##[error]  --> /checkout/tests/ui/attributes/instrument_fn.rs:13:9
   |
LL |         #[instrument_fn = "off"] //~ ERROR attribute cannot be used on
   |         ^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: `#[instrument_fn]` can only be applied to functions

error: `#[instrument_fn]` attribute cannot be used on traits
##[error]  --> /checkout/tests/ui/attributes/instrument_fn.rs:19:1
   |
LL | #[instrument_fn = "off"] //~ ERROR attribute cannot be used on
   | ^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: `#[instrument_fn]` can only be applied to functions

error: `#[instrument_fn]` attribute cannot be used on required trait methods
##[error]  --> /checkout/tests/ui/attributes/instrument_fn.rs:21:5
   |
LL |     #[instrument_fn = "off"] //~ ERROR attribute cannot be used on
   |     ^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: `#[instrument_fn]` can only be applied to functions with a body

error[E0805]: malformed `instrument_fn` attribute input
##[error]  --> /checkout/tests/ui/attributes/instrument_fn.rs:36:1
   |
LL | #[instrument_fn(entry = "on")] //~ ERROR malformed
   | ^^^^^^^^^^^^^^^--------------^
   |                |
   |                expected a single argument here
   |
help: must be of the form
   |
LL - #[instrument_fn(entry = "on")] //~ ERROR malformed
LL + #[instrument_fn = "on|off"] //~ ERROR malformed
   |

error[E0539]: malformed `instrument_fn` attribute input
##[error]  --> /checkout/tests/ui/attributes/instrument_fn.rs:39:1
   |
LL | #[instrument_fn] //~ ERROR malformed
   | ^^^^^^^^^^^^^^^^ valid arguments are "on" or "off"
   |
help: must be of the form
   |
LL | #[instrument_fn = "on|off"] //~ ERROR malformed
   |                 ++++++++++

error[E0539]: malformed `instrument_fn` attribute input
##[error]  --> /checkout/tests/ui/attributes/instrument_fn.rs:42:1
   |
LL | #[instrument_fn = 1] //~ ERROR malformed
   | ^^^^^^^^^^^^^^^^^^-^
   |                   |
   |                   valid arguments are "on" or "off"
   |
help: must be of the form
   |
LL - #[instrument_fn = 1] //~ ERROR malformed
LL + #[instrument_fn = "on|off"] //~ ERROR malformed
   |

error: aborting due to 10 previous errors

Some errors have detailed explanations: E0539, E0658, E0805.

@mejrs mejrs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I can't review the codegen side of this, but I can review the attribute stuff.

Can you add (compile error) tests for:

// crate level
#![instrument = "on"]

and

let _x = #[instrument = "on"] || {};

View changes since this review

fn instrument_function_attr<'ll>(
cx: &SimpleCx<'ll>,
sess: &Session,
instrument_fn: &Option<bool>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
instrument_fn: &Option<bool>,
instrument_fn: Option<bool>,

Comment on lines +580 to +581
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;

Error is the default value.

"xray-instruction-threshold",
&threshold.to_string(),
));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

😠

Suggested change

(unstable, import_trait_associated_functions, "1.86.0", Some(134691)),
/// Allows associated types in inherent impls.
(incomplete, inherent_associated_types, "1.52.0", Some(8995)),
/// Enable #[instrument_fn] on function (todo: tracking issue)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// Enable #[instrument_fn] on function (todo: tracking issue)
/// Enable #[instrument_fn] on functions

Old todo?

Some(llvm_mcount_intrinsic) => llvm_mcount_intrinsic.as_ref(),
None => sess.target.mcount.as_ref(),
};
// #[instrument_fn], the default is on.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Isn't it an error to use #[instrument_fn]? There is no default, the value must always be specified.

let mut instrument = None;
match args {
ArgParser::NameValue(nv) => {
if let Some(option) = nv.value_as_str()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is just stylistic, feel free to ignore.

Suggested change
if let Some(option) = nv.value_as_str()
if let Some(option @ (sym::on | sym::off)) = nv.value_as_str()

or my preference:

Suggested change
if let Some(option) = nv.value_as_str()
match nv.value_as_str(){
Some(sym::on) => Some(true),
Some(sym::off) => Some(false),
None => error,
}

Comment on lines +243 to +263
let mut never = options.never;
let mut always = options.always;

// Apply optional #[instrument_fn] override.
match instrument_fn {
Some(true) => {
always = true;
}
Some(false) => {
never = true;
}
None => {}
}
if options.never {

if never {
attrs.push(llvm::CreateAttrStringValue(cx.llcx, "function-instrument", "xray-never"));
}
if always {
attrs.push(llvm::CreateAttrStringValue(cx.llcx, "function-instrument", "xray-always"));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
let mut never = options.never;
let mut always = options.always;
// Apply optional #[instrument_fn] override.
match instrument_fn {
Some(true) => {
always = true;
}
Some(false) => {
never = true;
}
None => {}
}
if options.never {
if never {
attrs.push(llvm::CreateAttrStringValue(cx.llcx, "function-instrument", "xray-never"));
}
if always {
attrs.push(llvm::CreateAttrStringValue(cx.llcx, "function-instrument", "xray-always"));
}
// Apply optional #[instrument_fn] override.
match instrument_fn {
Some(true) => {
attrs.push(llvm::CreateAttrStringValue(cx.llcx, "function-instrument", "xray-always"));
}
Some(false) => {
attrs.push(llvm::CreateAttrStringValue(cx.llcx, "function-instrument", "xray-never"));
}
None => { /* invalid attribute input */ }
}

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 9, 2026
@rustbot

rustbot commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

InstructionSet(InstructionSetAttr),

/// Represents `#[instrument_fn]`
InstrumentFn(Option<bool>),

@mejrs mejrs Jun 9, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also a preference thing; I would use an enum for this (perhaps with a Err(guar) variant as well)

enum Instrument {
       On,
       Off,
}

View changes since the review

@rust-bors

rust-bors Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #157683) made this pull request unmergeable. Please resolve the merge conflicts.

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

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants