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

Calling non-const function core::slice::iter::<impl IntoIterator for &[u8]>::into_iter #125490

Open
jaudiger opened this issue May 24, 2024 · 3 comments
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) A-diagnostics Area: Messages for errors, warnings, and lints D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jaudiger
Copy link

jaudiger commented May 24, 2024

I didn't find a clear issue that was talking about that, and I'm clearly in the "nightly scape" of Rust here. I'm trying to build the following code (don't take attention to the possible unsafe part of this code, I omitted voluntary some part for better clarity):

Playground link:

#![feature(const_mut_refs)]
#![feature(const_for)]
#![feature(const_maybe_uninit_write)]
#![feature(effects)]

use core::mem::MaybeUninit;

#[must_use]
const fn from_slice_unchecked(from_slice: &[u8]) -> [MaybeUninit<u8>; 1]
{
    let mut vec = [MaybeUninit::uninit(); 1];

    for byte in from_slice {
        vec[0].write(*byte);
    }

    vec
}

fn main() {
    let _ = const { from_slice_unchecked(&[0]) };
}
error[E0080]: evaluation of `main::{constant#0}` failed
  --> src/main.rs:13:17
   |
13 |     for byte in from_slice {
   |                 ^^^^^^^^^^ calling non-const function `core::slice::iter::<impl IntoIterator for &[u8]>::into_iter`
   |
note: inside `from_slice_unchecked`
  --> src/main.rs:13:17
   |
13 |     for byte in from_slice {
   |                 ^^^^^^^^^^
note: inside `main::{constant#0}`
  --> src/main.rs:21:21
   |
21 |     let _ = const { from_slice_unchecked(&[0]) };
   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^

note: erroneous constant encountered
  --> src/main.rs:21:13
   |
21 |     let _ = const { from_slice_unchecked(&[0]) };
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0080`.

It does build if I don't const inline the call to from_slice_unchecked() though. But here, I'm wanted to create this buffer at build time and I don't find a way to do it "easily".

The closer issue I could find is #103265 which contains this closed PR #102225.

@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 24, 2024
@joboet
Copy link
Member

joboet commented May 25, 2024

for loops desugar to a call to into_iter, which is not a const function, and are therefore currently not allowed in const context.

It's standard practice to write a while loop over the indices instead, even if it is not very idiomatic:

#[must_use]
const fn from_slice_unchecked(from_slice: &[u8]) -> [MaybeUninit<u8>; 1]
{
    let mut vec = [MaybeUninit::uninit(); 1];

    let mut i = 0;
    while i < from_slice.len() {
        vec[i] = MaybeUninit::new(from_slice[i]);
        i += 1;
    }

    vec
}

(this version actually only uses stable features)

Edit: here is a cool example of the crc crate using this pattern to generate a lookup-table.

@workingjubilee workingjubilee added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. A-const-fn A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels May 27, 2024
@workingjubilee
Copy link
Member

The error for this should explain that.

@jaudiger
Copy link
Author

jaudiger commented May 27, 2024

@joboet Works perfectly in stable indeed, thanks for pointing me out in this direction. I'm now able to remove in my code the following feature flag: #![feature(const_for)], but I then encounter new blockers during the road to const_mut_refs. I'll focus on those new ones.

Anyway, thanks for your help. Since the trait IntoIterator is not available in const context, should I leave this issue open or close it if there is a duplicate already somewhere?

PS: thanks for the link, it was a good source of interesting line of code.

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, covers all const contexts (static, const fn, ...) A-diagnostics Area: Messages for errors, warnings, and lints D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants