diff options
| author | bors <bors@rust-lang.org> | 2024-10-25 07:42:32 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-10-25 07:42:32 +0000 |
| commit | 97ae1df8aa9fa6dfd29dced18b232d25208c4111 (patch) | |
| tree | 1d843a94b0e02cf1a2ed96993fbd4f4c7c51c11b /library/core/src | |
| parent | 017ae1b21f7be6dcdcfc95631e54bde806653a8a (diff) | |
| parent | 7f93af1a1ea4b8532750a56daacb877cc96d26ad (diff) | |
| download | rust-97ae1df8aa9fa6dfd29dced18b232d25208c4111.tar.gz rust-97ae1df8aa9fa6dfd29dced18b232d25208c4111.zip | |
Auto merge of #132128 - workingjubilee:rollup-uwqp2i2, r=workingjubilee
Rollup of 4 pull requests Successful merges: - #131457 (Expand `ptr::fn_addr_eq()` documentation.) - #132085 (Update StableMIR doc to reflect current status) - #132118 (Add support for `~const` item bounds) - #132125 (coverage: Emit LLVM intrinsics using the normal helper method) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'library/core/src')
| -rw-r--r-- | library/core/src/ptr/mod.rs | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index ea185f0fbe5..03cab232742 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -2107,13 +2107,39 @@ pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool { /// Compares the *addresses* of the two function pointers for equality. /// -/// Function pointers comparisons can have surprising results since -/// they are never guaranteed to be unique and could vary between different -/// code generation units. Furthermore, different functions could have the -/// same address after being merged together. +/// This is the same as `f == g`, but using this function makes clear that the potentially +/// surprising semantics of function pointer comparison are involved. +/// +/// There are **very few guarantees** about how functions are compiled and they have no intrinsic +/// “identity”; in particular, this comparison: +/// +/// * May return `true` unexpectedly, in cases where functions are equivalent. +/// +/// For example, the following program is likely (but not guaranteed) to print `(true, true)` +/// when compiled with optimization: +/// +/// ``` +/// # #![feature(ptr_fn_addr_eq)] +/// let f: fn(i32) -> i32 = |x| x; +/// let g: fn(i32) -> i32 = |x| x + 0; // different closure, different body +/// let h: fn(u32) -> u32 = |x| x + 0; // different signature too +/// dbg!(std::ptr::fn_addr_eq(f, g), std::ptr::fn_addr_eq(f, h)); // not guaranteed to be equal +/// ``` +/// +/// * May return `false` in any case. +/// +/// This is particularly likely with generic functions but may happen with any function. +/// (From an implementation perspective, this is possible because functions may sometimes be +/// processed more than once by the compiler, resulting in duplicate machine code.) +/// +/// Despite these false positives and false negatives, this comparison can still be useful. +/// Specifically, if +/// +/// * `T` is the same type as `U`, `T` is a [subtype] of `U`, or `U` is a [subtype] of `T`, and +/// * `ptr::fn_addr_eq(f, g)` returns true, +/// +/// then calling `f` and calling `g` will be equivalent. /// -/// This is the same as `f == g` but using this function makes clear -/// that you are aware of these potentially surprising semantics. /// /// # Examples /// @@ -2125,6 +2151,8 @@ pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool { /// fn b() { println!("b"); } /// assert!(!ptr::fn_addr_eq(a as fn(), b as fn())); /// ``` +/// +/// [subtype]: https://doc.rust-lang.org/reference/subtyping.html #[unstable(feature = "ptr_fn_addr_eq", issue = "129322")] #[inline(always)] #[must_use = "function pointer comparison produces a value"] |
