Repository navigation
Conversation
|
r? @clarfonthey rustbot has assigned @clarfonthey. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
cc @rust-lang/opsem, due to guaranteeing new things in user-facing documentation, although in an unstable API. |
| /// Returns the function pointer as a [`NonNull<Code>`], thus forgetting the signature and | ||
| /// everything else about the type except except the fact that it was a function pointer. |
There was a problem hiding this comment.
Should we perhaps also link to the docs talking about the hazards of function pointers? In particular, NonNull<Code> implements PartialEq, but it has the same problems as "normal" function pointers fn() with regards to comparisons and identity.
(also the wrong lint fires when you try to equate NonNull<Code>, the wide pointer lint fires instead of the fn pointer comparison lint, but that should be fixed in a different PR)
There was a problem hiding this comment.
That seems fair. Potentially something like, in general, you should not expect to glean any useful information from this pointer besides converting it back into a function, and to link fn_addr_eq to explain pitfalls.
(whose docs I don't think have been updated yet, but will be)
Allow it to be used for FFI/linking applications and not just Rust-to-Rust type erasure.
| /// from an [`FnPtr::as_ptr`] call from a function | ||
| /// pointer type that is ABI compatible. | ||
| /// `ptr` must have been obtained from calling [`FnPtr::as_ptr`] on a function pointer type | ||
| /// that is ABI-compatible, or from an equivalent foreign operation (e.g. requesting a function |
There was a problem hiding this comment.
ABI-compatible with what?
There was a problem hiding this comment.
I am not sure if this is correct. Self here may be e.g. fn(i32) -> i32, right? In that case the constructor needs to require that this is a safe function with that signature. Being ABI-compatible is not enough.
There was a problem hiding this comment.
Yeah, I'm not entirely sure this is correct either. It feels like we're back into the fn_addr_eq discussion again, where you really can't be sure that functions are compatible because the compiler might insert invisible nonsense in the prelude.
There was a problem hiding this comment.
I don't think this has anything to do with fn_addr_eq.
It's just that the safety invariant for fn(i32) -> i32 is "when this function is invoked with an i32, it will run without causing UB and if it returns, the result is an i32". The comment that's here right now is not strong enough to justify this property.
|
|
||
| /// Returns the function pointer as a [`NonNull<Code>`]. | ||
| /// Returns the function pointer as a [`NonNull<Code>`], thus forgetting the signature and | ||
| /// everything else about the type except except the fact that it was a function pointer. |
There was a problem hiding this comment.
| /// everything else about the type except except the fact that it was a function pointer. | |
| /// everything else about the function `self` points to. |
NonNull<Code> can be safely constructed to point to non-functions so arguably this forgets everything.
| #[rustc_deny_explicit_impl] | ||
| #[rustc_dyn_incompatible_trait] | ||
| pub trait FnPtr: Copy { | ||
| /// Returns the address of the function pointer. |
There was a problem hiding this comment.
| /// Returns the address of the function `self` points to. |
| /// The function pointer must have been obtained | ||
| /// from an [`FnPtr::as_ptr`] call from a function | ||
| /// pointer type that is ABI compatible. | ||
| /// `ptr` must have been obtained from calling [`FnPtr::as_ptr`] on a function pointer type |
There was a problem hiding this comment.
| /// `ptr` must have been obtained from calling [`FnPtr::as_ptr`] on a function pointer type | |
| /// `ptr` must have been obtained by calling [`FnPtr::as_ptr`] on a function pointer type |
I am not sure what the opsem part of this is, this is mostly changing the docs on a trait whose invariant is library-defined, no? |
|
I was under the impression that the machinery of |
|
When the trait is implemented for I have no idea which other types the trait is or will be implemented for. |
|
@RalfJung In the initial version of this PR, there was a new guarantee is that |
Yeah, from a libs perspective that's just incorrect. There is the strong boundary of language UB where the compiler is immediately allowed to eat your laundry, but in the standard library we like to make stronger guarantees so that safe code can't invoke UB. Even if it's not "immediately" UB, having a function pointer that cannot be called is a liability that we don't want to offer. |
|
@rustbot author (since there are still open questions) |
|
Reminder, once the PR becomes ready for a review, use |
@clarfonthey Turns out there's already precedent for making a distinction between "not immediately UB, but may cause UB later" and "all bets are immediately off" in the standard library. See #134598 |
|
I don't see such a distinction there? That is just spelling out more carefully what may or may not later be UB. |
|
The precedent I was referring to is specifically in the |
|
It's long discussion but |
|
I was referring to the context of the quote @theemathas made:
This was me referring to the current distinction which is most well codified in the |
So I still don't understand what the PR has to do with that but |
|
Right, and I guess my main issue communicating here is that I don't think that we should perform the exception here, where the distinction between when UB happens should be part of a guarantee. In general, the library team likes to guarantee as few possible exceptions to invariants as possible, and |
View all comments
(These changes are all intended to be “it obviously should be this”, not “let’s choose to allow this”. If we don’t want to allow one of these things, I will be happy to revise this text to be stricter.)
Allow
FnPtr::from_ptr()to be used for FFI/linking applications and not just Rust-to-Rust type erasure.Specify that calling
FnPtr::from_ptr()with an invalid pointer is not immediate UB.(T-opsem decided the relevant function pointer validity at Decide on the validity of function pointers unsafe-code-guidelines#440)
Tracking issue for
fn_static: #148768@rustbot label +A-docs +T-opsem +T-libs