@@ -2164,13 +2164,36 @@ pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool {
2164
2164
2165
2165
/// Compares the *addresses* of the two function pointers for equality.
2166
2166
///
2167
- /// Function pointers comparisons can have surprising results since
2168
- /// they are never guaranteed to be unique and could vary between different
2169
- /// code generation units. Furthermore, different functions could have the
2170
- /// same address after being merged together.
2167
+ /// This is the same as `f == g`, but using this function makes clear that the potentially
2168
+ /// surprising semantics of function pointer comparison are involved.
2169
+ /// There are very few guarantees about how functions are compiled and they have no intrinsic
2170
+ /// “identity”; in particular, this comparison:
2171
+ ///
2172
+ /// * May return `true` unexpectedly, in cases where functions are equivalent.
2173
+ /// For example, the following program is likely (but not guaranteed) to print `(true, true)`
2174
+ /// when compiled with optimization:
2175
+ ///
2176
+ /// ```
2177
+ /// # #![feature(ptr_fn_addr_eq)]
2178
+ /// let f: fn(i32) -> i32 = |x| x;
2179
+ /// let g: fn(i32) -> i32 = |x| x + 0; // different closure, different body
2180
+ /// let h: fn(u32) -> u32 = |x| x + 0; // different signature too
2181
+ /// dbg!(std::ptr::fn_addr_eq(f, g), std::ptr::fn_addr_eq(f, h));
2182
+ /// ```
2183
+ ///
2184
+ /// * May return `false` in any case.
2185
+ /// This is particularly likely with generic functions but may happen with any function.
2186
+ /// (From an implementation perspective, this is possible because functions may sometimes be
2187
+ /// processed more than once by the compiler, resulting in duplicate machine code.)
2188
+ ///
2189
+ /// Despite these false positives and false negatives, this comparison can still be useful.
2190
+ /// Specifically, if
2191
+ ///
2192
+ /// * `T` is the same type as `U`, `T` is a [subtype] of `U`, or `U` is a [subtype] of `T`, and
2193
+ /// * `ptr::fn_addr_eq(f, g)` returns true,
2194
+ ///
2195
+ /// then calling `f` and calling `g` will be equivalent.
2171
2196
///
2172
- /// This is the same as `f == g` but using this function makes clear
2173
- /// that you are aware of these potentially surprising semantics.
2174
2197
///
2175
2198
/// # Examples
2176
2199
///
@@ -2182,6 +2205,9 @@ pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool {
2182
2205
/// fn b() { println!("b"); }
2183
2206
/// assert!(!ptr::fn_addr_eq(a as fn(), b as fn()));
2184
2207
/// ```
2208
+ ///
2209
+ /// [subtype]: https://doc.rust-lang.org/reference/subtyping.html
2210
+
2185
2211
#[ unstable( feature = "ptr_fn_addr_eq" , issue = "129322" ) ]
2186
2212
#[ inline( always) ]
2187
2213
#[ must_use = "function pointer comparison produces a value" ]
0 commit comments