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"]

`