Expand ptr::fn_addr_eq()
documentation. · qinheping/verify-rust-std@0ce4f76 (original) (raw)
`@@ -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"]
`