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

Const constructors from str, from slice for ArrayString, ArrayVec #205

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

bluss
Copy link
Owner

@bluss bluss commented Nov 7, 2021

  • Add from_str_const constructor for ArrayString

  • Add from_slice_const constructor for ArrayVec

We can't make the ArrayVec constructors generic, not even where T: Copy,
so they are just templated out with macros for the integer types, quite limited.

These use "const error" for error handling - using panic would need Rust 1.57 (not yet released).

Closes #204

bluss added 2 commits November 7, 2021 12:36
We can't make these generic, not even where T: Copy, so they are just
templated out with macros for the integer types, quite limited.
@aldanor
Copy link

aldanor commented Nov 7, 2021

Neat!

About compile-time const, for pre-1.57, you can use a hack like this btw:

pub(crate) struct Assert<const L: usize, const R: usize>;

impl<const L: usize, const R: usize> Assert<L, R> {
    pub const LENGTH_LT_CAPACITY: usize = R - L - 1;
}

macro_rules! assert_length_lt_capacity_const {
    ($len:expr, $cap:expr) => {
        #[allow(path_statements)]
        { Assert::<$len, $cap>::LENGTH_LT_CAPACITY; }
    }
}

fn main() {
    assert_length_lt_capacity_const!(2, 3);
    // assert_length_lt_capacity_const!(3, 3); // compile-time error
}

@bluss
Copy link
Owner Author

bluss commented Nov 7, 2021

I see. That's similar to what I already added for it to work on stable, but maybe your version has better error messages

@aldanor
Copy link

aldanor commented Nov 7, 2021

It's not perfect, but quite readable. Perhaps could be improved by something like

impl<const LEN: usize, const CAP: usize> Assert<LEN, CAP> {
    pub const OK: usize = CAP - LEN - 1; /* insufficient array capacity */
}

This yields:

error: any use of this value will cause an error
 --> src/main.rs:4:27
  |
4 |     pub const OK: usize = CAP - LEN - 1; /* insufficient array capacity */
  |     ----------------------^^^^^^^^^^^^^-
  |                           |
  |                           attempt to compute `0_usize - 1_usize`, which would overflow

@bluss
Copy link
Owner Author

bluss commented Nov 7, 2021

It seems like the length - coming from s.len() can't be used there in current Rust, unfortunately.

@aldanor
Copy link

aldanor commented Nov 7, 2021

It seems like the length - coming from s.len() can't be used there in current Rust, unfortunately.

Ah, yea, indeed, it would only work with "true consts"...

So what's the plan then, wait till MSRV >= 1.57 bump for the crate eventually? (assuming passing s.len() to const assert works there)

@bluss
Copy link
Owner Author

bluss commented Nov 7, 2021

It won't work there either (I'm developing on nightly locally, so that's the first behaviour I see). I'm not sure what the missing feature would be called.

But I'll elaborate - on Rust 1.57 we can panic in constants, so that's better than the current solutions. Not a reason to bump on its own, though (?)

@aldanor
Copy link

aldanor commented Sep 9, 2022

Sorry for bringing the old issue back from the dead :) Wonder if this would be feasible, given we can panic in constants?

Const constructors are still a big missing piece...

@utkarshgupta137
Copy link

Bump

@jon-zu
Copy link

jon-zu commented Sep 19, 2023

Is there a reason to use slices instead of an Array [T; M] with an assertion that M <= CAP (assert works fine now in const fns). I've tried this successfully, the only downside is Copy is still required, and we have to pass the Array as reference else the compiler complains that It can't determine the destructor.

I would argue this const constructor for ArrayString and one for Arrays covers almost all cases.

@GummyGun
Copy link

Is there any reason this is not currently in yet.
Is the crate dead/stalled?

@nyovaya
Copy link

nyovaya commented Nov 15, 2024

Is this still Work in Progress? Or are we just waiting for a feature to stabilize?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Const constructor for strings via a macro?
6 participants