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

Tracking issue for const slice::from_raw_parts #67456

Open
1 task done
DutchGhost opened this issue Dec 20, 2019 · 20 comments · May be fixed by #130403
Open
1 task done

Tracking issue for const slice::from_raw_parts #67456

DutchGhost opened this issue Dec 20, 2019 · 20 comments · May be fixed by #130403
Labels
A-const-eval Area: constant evaluation (mir interpretation) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. A-raw-pointers Area: raw pointers, MaybeUninit, NonNull A-slice Area: [T] B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. Libs-Small Libs issues that are considered "small" or self-contained Libs-Tracked Libs issues that are tracked on the team's project board. proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@DutchGhost
Copy link
Contributor

DutchGhost commented Dec 20, 2019

Make slice::from_raw_parts and slice::from_raw_parts_mut a const fn available under a feature flag.
This would require a change in the ptr module as well, as slice module just forwards to it.

slice::from_raw_parts[mut] is used in alot of places (e.g slice::from_ref[mut], which would get one step closer into constification if slice::from_raw_parts[mut] is a const fn.

Here is a little playground to show it's possible:
https://play.rust-lang.org/?version=nightly&mode=release&edition=2018&gist=dd5c506a3e082c619f557d972e9956ff

In order to get this working, the following functions and functionalities need to be constified:


Implementation PR for ptr::slice_from_raw_parts: #67462


Partially stabilized in #97522; remaining unstable functions:

// core::ptr
pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T];

// core::slice
pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T];

// core::ptr::NonNull
pub const fn slice_from_raw_parts(data: NonNull<T>, len: usize) -> Self
Centril added a commit to Centril/rust that referenced this issue Dec 21, 2019
…ts, r=dtolnay

Make ptr::slice_from_raw_parts a const fn available under a feature flag

A first step in the direction of rust-lang#67456 .
This makes `ptr::slice_from_raw_parts` and `ptr::slice_from_raw_parts_mut` available as a const fn under a feature flag.
@Centril Centril added T-lang Relevant to the language team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. A-const-eval Area: constant evaluation (mir interpretation) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. labels Dec 21, 2019
Centril added a commit to Centril/rust that referenced this issue Dec 21, 2019
…ts, r=dtolnay

Make ptr::slice_from_raw_parts a const fn available under a feature flag

A first step in the direction of rust-lang#67456 .
This makes `ptr::slice_from_raw_parts` and `ptr::slice_from_raw_parts_mut` available as a const fn under a feature flag.
@SimonSapin SimonSapin changed the title feature request: const slice::from_raw_parts Tracking issue for const slice::from_raw_parts Jan 21, 2020
@DoumanAsh
Copy link

DoumanAsh commented Apr 22, 2020

Is there particular reason why it remains gated by feature flag instead of just being const fn as it is?

@DutchGhost
Copy link
Contributor Author

DutchGhost commented Apr 23, 2020

Is there particular reason why it remains gated by feature flag instead of just being const fn as it is?

The constant versions of function's and methods in libcore/libstd need a period of time under a feature flag before they can be stabilized as a const function/method. Const functions are 'relatively' new, and the ability of what one can do inside isn't fully determined yet I think.
One of those abilities is how to handle raw pointers, which slice::from_raw_parts[mut] needs.

@josephlr
Copy link
Contributor

@DutchGhost would it make sense for the slice::{from_raw_parts[_mut], from_ref, from_mut} to be constified behind this feature as well? The only thing that seems blocking that is this debug_assert which calls is_aligned_and_not_null.

Checking the alignment will need support from the MIR interpreter, see #62420

@KodrAus KodrAus added A-slice Area: [T] B-unstable Blocker: Implemented in the nightly compiler and unstable. Libs-Small Libs issues that are considered "small" or self-contained Libs-Tracked Libs issues that are tracked on the team's project board. A-raw-pointers Area: raw pointers, MaybeUninit, NonNull labels Jul 29, 2020
@DutchGhost
Copy link
Contributor Author

DutchGhost commented Dec 5, 2020

@DutchGhost would it make sense for the slice::{from_raw_parts[_mut], from_ref, from_mut} to be constified behind this feature as well? The only thing that seems blocking that is this debug_assert which calls is_aligned_and_not_null.

Checking the alignment will need support from the MIR interpreter, see #62420

I'd say this indeed should fall under the same feature, as you wouldnt want to have 2 seperate features you need to track for really just one thing. Also I think once #79684 has landed, having a const slice::from_raw_parts is possible!!

@mbartlett21
Copy link
Contributor

Cc. #57563

@DutchGhost
Copy link
Contributor Author

This can now be implemented it seems. But Im not sure whether its decided yet what the plan is on allowing to cast pointers to usizes in const contexts, which is needed for is_aligned_and_not_null:

#![feature(const_ptr_is_null)]
#![feature(const_raw_ptr_to_usize_cast)]
#![feature(const_raw_ptr_deref)]
#![feature(const_slice_from_raw_parts)]
#![feature(const_panic)]


mod slice {
    use core::mem;
    use core::ptr;
    
    pub(crate) const unsafe fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
        !ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
    }

    pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
        debug_assert!(
            is_aligned_and_not_null(data),
            "attempt to create unaligned or null slice"
        );
        debug_assert!(
            mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
            "attempt to create slice covering at least half the address space"
        );
        // SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
        unsafe { &*ptr::slice_from_raw_parts(data, len) }
    }
    
    pub const fn from_ref<T>(reference: &T) -> &[T] {
        unsafe {
            from_raw_parts(reference, 1)
        }
    }
}

const X: &[usize] = slice::from_ref(&1);

fn main() {
    dbg!(X);
}

@mbartlett21
Copy link
Contributor

@DutchGhost
You can type ptr as usize, but as soon as you try that in const-eval, you get a compiler error:

error: any use of this value will cause an error
  --> src/main.rs:13:27
   |
13 |         !ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
   |                           ^^^^^^^^^^^^
   |                           |
   |                           "pointer-to-integer cast" needs an rfc before being allowed inside constants
   |                           inside `is_aligned_and_not_null::<usize>` at src/main.rs:13:27
   |                           inside `slice::from_raw_parts::<usize>` at src/main.rs:18:13
   |                           inside `slice::from_ref::<usize>` at src/main.rs:31:13
   |                           inside `X` at src/main.rs:36:21
...
36 | const X: &[usize] = slice::from_ref(&1);
   | ----------------------------------------
   |
   = note: `#[deny(const_err)]` on by default

(playground)

@DutchGhost

This comment has been minimized.

@WaffleLapkin
Copy link
Member

WaffleLapkin commented Oct 30, 2021

To clarify: this issue is currently tracking the following APIs being const:

// core::ptr
pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T];
pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T];

// core::slice
pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T];
pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T];

The former two methods were implemented in #67462 and the latter two were implemented in #90377.

slice::from_{ref,mut} mentioned in the issue text as a const fn is tracked in #90206.

@tobz
Copy link

tobz commented Mar 11, 2022

As an interested party: is there a path to eventual stabilization here, at least for some of the incremental work that is required? For example, std::ptr::slice_from_raw_parts has been available as a const fn (behind a feature flag) for over 2 years now... but I can't seem to find any actionable comments that provide a reason for it to not be stabilized.

Happy to try and learn/help to get it over the line. 🙏🏻

@WaffleLapkin
Copy link
Member

I think that these API are ready for stabilization 🤔

APIs that return &mut/*mut are probably blocked on #57349, but the &/*const versions can be stabilized and only need https://github.com/orgs/rust-lang/teams/wg-const-eval FCP

@joshtriplett
Copy link
Member

Partial stabilization in FCP at #97522

@joshtriplett
Copy link
Member

The remainder is blocked on #57349.

@joshtriplett joshtriplett added the S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. label Jun 29, 2022
@the8472
Copy link
Member

the8472 commented Mar 20, 2023

I updated the issue description to list the methods in question and added NonNull::slice_from_raw_parts since #97506 changes the tracking issue to this one too.

Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Mar 27, 2023
…rom-raw-parts, r=m-ou-se,the8472

Stabilize `nonnull_slice_from_raw_parts`

FCP is done: rust-lang#71941 (comment)
Note that this doesn't const-stabilize `NonNull::slice_from_raw_parts` as `slice_from_raw_parts_mut` isn't const-stabilized yet. Given rust-lang#67456 and rust-lang#57349, it's not likely available soon, meanwhile, stabilizing only the feature makes some sense, I think.

Closes rust-lang#71941
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Mar 27, 2023
…rom-raw-parts, r=m-ou-se,the8472

Stabilize `nonnull_slice_from_raw_parts`

FCP is done: rust-lang#71941 (comment)
Note that this doesn't const-stabilize `NonNull::slice_from_raw_parts` as `slice_from_raw_parts_mut` isn't const-stabilized yet. Given rust-lang#67456 and rust-lang#57349, it's not likely available soon, meanwhile, stabilizing only the feature makes some sense, I think.

Closes rust-lang#71941
@eduardosm
Copy link
Contributor

Why is this blocked on #57349? Is there any issue about using raw mutable pointers in const fns?

ptr::slice_from_raw_parts_mut can be currently emulated with ptr::slice_from_raw_parts(..).cast_mut() anyways.

@WaffleLapkin
Copy link
Member

@eduardosm I don't think using ptr::slice_from_raw_parts(..).cast_mut() it actually useful. Since you can't get &mut or any other pointer with provenance that allows writing, ptr::slice_from_raw_parts will always return a pointer via which you cannot write. So while cast_mut() returns a *mut, you can't actually use it mutably.

@eduardosm
Copy link
Contributor

I am actually interested in NonNull::slice_from_raw_parts rather than ptr::slice_from_raw_parts_mut. I gave that example because the former is implemented on top of the later, so:

  • ptr::slice_from_raw_parts_mut can be emulated with ptr::slice_from_raw_parts(..).cast_mut(), with questionable usefulness.
  • NonNull::slice_from_raw_parts can be emulated with NonNull::new_unchecked(ptr::slice_from_raw_parts(data.as_ptr(), len).cast_mut()), which is useful for immutable access (but it requires an unsafe block, unlike NonNull::slice_from_raw_parts).

@eduardosm eduardosm linked a pull request Sep 15, 2024 that will close this issue
workingjubilee added a commit to workingjubilee/rustc that referenced this issue Sep 19, 2024
… r=dtolnay

Support `char::encode_utf8` in const scenarios.

This PR implements [`rust-lang/rfcs#3696`](rust-lang/rfcs#3696).

This assumes [`const_slice_from_raw_parts_mut`](rust-lang#67456).
bors added a commit to rust-lang-ci/rust that referenced this issue Sep 19, 2024
…=dtolnay

Support `char::encode_utf8` in const scenarios.

This PR implements [`rust-lang/rfcs#3696`](rust-lang/rfcs#3696).

This assumes [`const_slice_from_raw_parts_mut`](rust-lang#67456).
@RalfJung
Copy link
Member

RalfJung commented Sep 19, 2024

@rust-lang/libs-api this should be ready. :) It const-stabilizes some long-stable functions, which is possible now that &mut is const-stable.

@RalfJung RalfJung added the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Sep 19, 2024
@dtolnay dtolnay removed the T-lang Relevant to the language team, which will review and decide on the PR/issue. label Sep 19, 2024
@rfcbot
Copy link

rfcbot commented Sep 19, 2024

Team member @dtolnay has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Sep 19, 2024
@dtolnay dtolnay removed I-libs-api-nominated Nominated for discussion during a libs-api team meeting. S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. labels Sep 19, 2024
RalfJung pushed a commit to RalfJung/miri that referenced this issue Sep 21, 2024
Support `char::encode_utf8` in const scenarios.

This PR implements [`rust-lang/rfcs#3696`](rust-lang/rfcs#3696).

This assumes [`const_slice_from_raw_parts_mut`](rust-lang/rust#67456).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: constant evaluation (mir interpretation) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. A-raw-pointers Area: raw pointers, MaybeUninit, NonNull A-slice Area: [T] B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. Libs-Small Libs issues that are considered "small" or self-contained Libs-Tracked Libs issues that are tracked on the team's project board. proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.