Rollup merge of #148279 - IntegralPilot:master, r=hkBst

rustc_builtin_macros: rename bench parameter to avoid collisions with user-defined function names

Resolves rust-lang/rust#148275 by preventing name collisions in the `#[bench]` macro.

Previously, a user-defined function named "b" could not be benchmarked because
the macro-generated lambda identity collided with the same name. We now generate
the lambda ident as `__bench_<function_name>`, ensuring it is always distinct
from the user’s function.

Because the prefix is applied recursively (e.g. benchmarking `__bench_b`
produces a lambda ident `__bench___bench_b`), there is no possible function
name that can equal its corresponding lambda ident. This guarantees that
the user can safely bench a function of any valid name without risk of
identifier collision.
This commit is contained in:
Stuart Cook 2025-11-09 13:22:28 +11:00 committed by GitHub
commit 645aa9232b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -207,30 +207,30 @@ pub(crate) fn expand_test_or_bench(
};
let test_fn = if is_bench {
// A simple ident for a lambda
let b = Ident::from_str_and_span("b", attr_sp);
// avoid name collisions by using the function name within the identifier, see bug #148275
let bencher_param =
Ident::from_str_and_span(&format!("__bench_{}", fn_.ident.name), attr_sp);
cx.expr_call(
sp,
cx.expr_path(test_path("StaticBenchFn")),
thin_vec![
// #[coverage(off)]
// |b| self::test::assert_test_result(
// |__bench_fn_name| self::test::assert_test_result(
coverage_off(cx.lambda1(
sp,
cx.expr_call(
sp,
cx.expr_path(test_path("assert_test_result")),
thin_vec![
// super::$test_fn(b)
// super::$test_fn(__bench_fn_name)
cx.expr_call(
ret_ty_sp,
cx.expr_path(cx.path(sp, vec![fn_.ident])),
thin_vec![cx.expr_ident(sp, b)],
thin_vec![cx.expr_ident(sp, bencher_param)],
),
],
),
b,
bencher_param,
)), // )
],
)