Skip to content
Closed
Changes from 2 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
612adbb
Bounds-check with PtrMetadata instead of Len in MIR
scottmcm Dec 2, 2024
2ce89ee
Add a test for mangling of named constants in const generics and arra…
oli-obk Dec 9, 2024
9ecdc54
Try to evaluate constants in legacy mangling
oli-obk Dec 9, 2024
eb10db0
Make some types and methods related to Polonius + Miri public.
willcrichton Dec 12, 2024
de53fe2
coverage: Tidy up creation of covmap records
Zalathar Dec 12, 2024
5f5745b
coverage: Tidy up creation of covfun records
Zalathar Dec 12, 2024
2a6a7be
don't show the full linker args unless `--verbose` is passed
jyn514 Dec 25, 2023
3a90c47
Fix powerpc64 big-endian FreeBSD ABI
taiki-e Oct 25, 2024
7fb2fc0
feat: clarify how to use `black_box()`
BD103 Dec 5, 2024
2e412fe
Remove `Lexer`'s dependency on `Parser`.
nnethercote Dec 12, 2024
8200c1e
rustdoc-search: fix mismatched path when parent re-exported twice
notriddle Dec 12, 2024
4d5d470
Make BorrowSet/BorrowData fields accessible via public getters
willcrichton Dec 12, 2024
65a54a7
Tweak multispan rendering
estebank Dec 11, 2024
49a22a4
Filter empty lines, comments and delimiters from previous to last mul…
estebank Dec 11, 2024
38249be
Don't retag the `PtrMetadata(&raw const *_n)` in slice indexing
scottmcm Dec 13, 2024
98318c5
rustdoc-search: update test with now-shorter function path
notriddle Dec 13, 2024
ad82d9f
Fix miri tests
estebank Dec 12, 2024
9f1044e
Account for `///` when rendering multiline spans
estebank Dec 13, 2024
d2a98f7
Update compiler/rustc_const_eval/src/interpret/step.rs
scottmcm Dec 13, 2024
96dbb58
Rollup merge of #132150 - taiki-e:ppc64-freebsd-abi, r=pnkfelix
Zalathar Dec 14, 2024
5d965bf
Rollup merge of #133633 - jyn514:hide-linker-args, r=bjorn3,jyn514
Zalathar Dec 14, 2024
7a8f680
Rollup merge of #133734 - scottmcm:lower-indexing-to-ptrmetadata, r=d…
Zalathar Dec 14, 2024
4a9526d
Rollup merge of #133942 - BD103:black-box-docs, r=saethlin
Zalathar Dec 14, 2024
3b5b129
Rollup merge of #134081 - oli-obk:push-prpsqxxynxnq, r=BoxyUwU
Zalathar Dec 14, 2024
4fcc959
Rollup merge of #134181 - estebank:trim-render, r=oli-obk
Zalathar Dec 14, 2024
8e2a805
Rollup merge of #134191 - willcrichton:dev, r=RalfJung,lqd
Zalathar Dec 14, 2024
a326ab7
Rollup merge of #134192 - nnethercote:rm-Lexer-Parser-dep, r=compiler…
Zalathar Dec 14, 2024
b3c2d8f
Rollup merge of #134208 - Zalathar:covmap-covfun, r=compiler-errors
Zalathar Dec 14, 2024
086c41b
Rollup merge of #134231 - notriddle:notriddle/mismatched-path, r=Guil…
Zalathar Dec 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 89 additions & 3 deletions library/core/src/hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,13 +310,17 @@ pub fn spin_loop() {
/// behavior in the calling code. This property makes `black_box` useful for writing code in which
/// certain optimizations are not desired, such as benchmarks.
///
/// <div class="warning">
///
/// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The
/// extent to which it can block optimisations may vary depending upon the platform and code-gen
/// backend used. Programs cannot rely on `black_box` for *correctness*, beyond it behaving as the
/// identity function. As such, it **must not be relied upon to control critical program behavior.**
/// This also means that this function does not offer any guarantees for cryptographic or security
/// purposes.
///
/// </div>
///
/// [`std::convert::identity`]: crate::convert::identity
///
/// # When is this useful?
Expand Down Expand Up @@ -357,7 +361,7 @@ pub fn spin_loop() {
/// ```
/// use std::hint::black_box;
///
/// // Same `contains` function
/// // Same `contains` function.
/// fn contains(haystack: &[&str], needle: &str) -> bool {
/// haystack.iter().any(|x| x == &needle)
/// }
Expand All @@ -366,8 +370,13 @@ pub fn spin_loop() {
/// let haystack = vec!["abc", "def", "ghi", "jkl", "mno"];
/// let needle = "ghi";
/// for _ in 0..10 {
/// // Adjust our benchmark loop contents
/// black_box(contains(black_box(&haystack), black_box(needle)));
/// // Force the compiler to run `contains`, even though it is a pure function whose
/// // results are unused.
/// black_box(contains(
/// // Prevent the compiler from making assumptions about the input.
/// black_box(&haystack),
/// black_box(needle),
/// ));
/// }
/// }
/// ```
Expand All @@ -382,6 +391,83 @@ pub fn spin_loop() {
///
/// This makes our benchmark much more realistic to how the function would actually be used, where
/// arguments are usually not known at compile time and the result is used in some way.
///
/// # How to use this
///
/// In practice, `black_box` serves two purposes:
///
/// 1. It prevents the compiler from making optimizations related to the value returned by `black_box`
/// 2. It forces the value passed to `black_box` to be calculated, even if the return value of `black_box` is unused
///
/// ```
/// use std::hint::black_box;
///
/// let zero = 0;
/// let five = 5;
///
/// // The compiler will see this and remove the `* five` call, because it knows that multiplying
/// // any integer by 0 will result in 0.
/// let c = zero * five;
///
/// // Adding `black_box` here disables the compiler's ability to reason about the first operand in the multiplication.
/// // It is forced to assume that it can be any possible number, so it cannot remove the `* five`
/// // operation.
/// let c = black_box(zero) * five;
/// ```
///
/// While most cases will not be as clear-cut as the above example, it still illustrates how
/// `black_box` can be used. When benchmarking a function, you usually want to wrap its inputs in
/// `black_box` so the compiler cannot make optimizations that would be unrealistic in real-life
/// use.
///
/// ```
/// use std::hint::black_box;
///
/// // This is a simple function that increments its input by 1. Note that it is pure, meaning it
/// // has no side-effects. This function has no effect if its result is unused. (An example of a
/// // function *with* side-effects is `println!()`.)
/// fn increment(x: u8) -> u8 {
/// x + 1
/// }
///
/// // Here, we call `increment` but discard its result. The compiler, seeing this and knowing that
/// // `increment` is pure, will eliminate this function call entirely. This may not be desired,
/// // though, especially if we're trying to track how much time `increment` takes to execute.
/// let _ = increment(black_box(5));
///
/// // Here, we force `increment` to be executed. This is because the compiler treats `black_box`
/// // as if it has side-effects, and thus must compute its input.
/// let _ = black_box(increment(black_box(5)));
/// ```
///
/// There may be additional situations where you want to wrap the result of a function in
/// `black_box` to force its execution. This is situational though, and may not have any effect
/// (such as when the function returns a zero-sized type such as [`()` unit][unit]).
///
/// Note that `black_box` has no effect on how its input is treated, only its output. As such,
/// expressions passed to `black_box` may still be optimized:
///
/// ```
/// use std::hint::black_box;
///
/// // The compiler sees this...
/// let y = black_box(5 * 10);
///
/// // ...as this. As such, it will likely simplify `5 * 10` to just `50`.
/// let _0 = 5 * 10;
/// let y = black_box(_0);
/// ```
///
/// In the above example, the `5 * 10` expression is considered distinct from the `black_box` call,
/// and thus is still optimized by the compiler. You can prevent this by moving the multiplication
/// operation outside of `black_box`:
///
/// ```
/// use std::hint::black_box;
///
/// // No assumptions can be made about either operand, so the multiplication is not optimized out.
/// let y = black_box(5) * black_box(10);
/// ```
#[inline]
#[stable(feature = "bench_black_box", since = "1.66.0")]
#[rustc_const_unstable(feature = "const_black_box", issue = "none")]
Expand Down