Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ACP: Add from_ref and from_mut constructors to core::ptr::NonNull. #448

Closed
bjoernager opened this issue Sep 26, 2024 · 1 comment
Closed
Labels
ACP-accepted API Change Proposal is accepted (seconded with no objections) api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api

Comments

@bjoernager
Copy link

Proposal

Problem statement

To create a core::ptr::NonNull object from a reference, one can simply use the provided From implementation. But in constant expressions (const functions/blocks), trait methods are (mostly) forbidden, and one currently has to resort to more complicated work arounds.

Motivating examples or use cases

To circumvent the trait restrictions, one could instead first create a raw pointer and then construct the relevant non-null pointer from the raw pointer:

let mut value = /* something... */;

// SAFETY: References can never be null.
let non_null = unsafe { core::ptr::NonNull::new_unchecked(core::ptr::from_mut(&mut value)) };

with raw_ref_op, however, this can be simplified to the following:

let mut value = /* something... */;

// SAFETY: References can never be null.
let non_null = unsafe { core::ptr::NonNull::new_unchecked(&raw mut value) };

But this is still unnecessarily complicated for an operation that should be a no-op.

Solution sketch

I propose adding the from_ref and from_mut constructors for parity with the similar global functions in core::ptr:

// core::ptr

impl<T: ?Sized> NonNull<T> {
    pub const fn from_ref(r: &T) -> Self;

    pub const fn from_mut(r: &mut T) -> Self;
}

Which would allow directly constructing a non-null pointer like the following:

let mut value = /* something... */;

let non_null = core::ptr::NonNull::from_mut(&mut value);

The latter constructor is inherently unblocked by the stabilisation of const_mut_refs.

Alternatives

An alternative solution would be to directly allow primitive casts to the NonNull type:

let mut value = /* something... /*;

let non_null = &mut value as core::ptr::NonNull;

Although I doubt this would actually be preferred over the primary solution.

Another alternative would be to allow traits in constant expressions, but this is already covered by const_trait_impl.

Links and related work

The #130822 PR implements the from_ref and from_mut constructors behind the non_null_from_ref feature gate. The #130823 issue tracks this feature gate.

@bjoernager bjoernager added api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api labels Sep 26, 2024
@dtolnay
Copy link
Member

dtolnay commented Sep 26, 2024

👍 This makes sense to me. Thank you for your work on this feature.

@dtolnay dtolnay closed this as completed Sep 26, 2024
@dtolnay dtolnay added the ACP-accepted API Change Proposal is accepted (seconded with no objections) label Sep 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ACP-accepted API Change Proposal is accepted (seconded with no objections) api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api
Projects
None yet
Development

No branches or pull requests

2 participants