Skip to content

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

Open
bluss wants to merge 2 commits into
masterfrom
from-const
Open

bluss wants to merge 2 commits into
masterfrom
from-const

Conversation

@bluss

@bluss bluss commented Nov 7, 2021 •

Copy link
Copy Markdown
Owner
  • 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

aldanor commented Nov 7, 2021

Copy link
Copy Markdown

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

bluss commented Nov 7, 2021

Copy link
Copy Markdown
Owner Author

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

aldanor commented Nov 7, 2021

Copy link
Copy Markdown

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

bluss commented Nov 7, 2021

Copy link
Copy Markdown
Owner Author

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

@aldanor

aldanor commented Nov 7, 2021 •

Copy link
Copy Markdown

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

bluss commented Nov 7, 2021 •

Copy link
Copy Markdown
Owner Author

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

aldanor commented Sep 9, 2022

Copy link
Copy Markdown

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
Copy Markdown

Bump

@jon-zu

jon-zu commented Sep 19, 2023 •

Copy link
Copy Markdown

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
Copy Markdown

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

@ghost

ghost commented Nov 15, 2024 •

Copy link
Copy Markdown

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

@Ad1n

Ad1n commented Oct 5, 2026 •

Copy link
Copy Markdown

Rebased this onto current master as #327 (#327) ArrayString half only . Your commit authorship preserved : it cherry-picked cleanly with no conflicts.

The main thing I added is evidence on the MSRV question: I built with rustc 1.51.0 in both std and no_std and confirmed from_str_const needs no bump - a valid const compiles an over-long one is a compile error at 1.51. So the 1.57 concern from #294/#296 doesn't apply to this half. Also fixed len as u32 - > len as LenUint which would otherwise break 16-bit targets since #234. All CI green, including miri.

Happy to close #327 if youd rather land yours directly - i mainly wanted to show it still applies.

This branch has not been deployed

No deployments
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