Skip to content

Make len and is_empty of Vec and String const - #700

Open
sundew-sensing-admin wants to merge 1 commit into
rust-embedded:mainfrom
sundew-sensing:const-len-is-empty
Open

sundew-sensing-admin wants to merge 1 commit into
rust-embedded:mainfrom
sundew-sensing:const-len-is-empty

Conversation

@sundew-sensing-admin

Copy link
Copy Markdown

Builds on #698, so the first commit is duplicate. Probably easiest to wait until that is merged.

Vec and String had no len of their own. Calls went through Deref to the slice or str inside, and deref is a trait method, which can't be called in const contexts. Both methods now read the stored length directly, so they can be used in const contexts, including on VecView and StringView.

This adds a const as_usize helper, because the existing into_usize that LenType provides is a trait method, which can't be called in const either. As with to_len_type and from_usize, the two are kept side by side.

I considered not doing this and just waiting for const deref to become stable, but heapless aims to support older compilers to, so I thought this would be nice. Also not all boards I'm supporting have an up to date nightly compiler :) I guess in the far future this PR becomes obsolete.

Related: #515 (same as with #698)

AI disclosure
Same as with #698.
I used Claude (Opus 5.5 extra-high) to

  • figure out that I need this const in my own codebase,
  • dig through the issues and PRs to figure out why this was not const,
  • create the fix,
  • assist in learning that the fix makes sense,
  • and draft the above message.

I manually verified and adjusted of course :)

`Vec` and `String` had no `len` of their own. Calls went through
`Deref` to the slice or `str` inside, and `deref` is a trait method,
which can't be called in const contexts. Both methods now read the
stored length directly, so they can be used in const contexts,
including on `VecView` and `StringView`.

This adds a const `as_usize` helper, because the existing `into_usize`
that `LenType` provides is a trait method, which can't be called in
const either. As with `to_len_type` and `from_usize`, the two are kept
side by side.
@surgura

surgura commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

Author is me, logged in on the wrong account :)

@sgued

sgued commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

This PR dosn't solev any problem until .push() can be made const. Given the required added unsafe, I prefer not to merge it.

@sgued sgued closed this Nov 7, 2026
@surgura

surgura commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

I made this because I do have a use case for it.

Non-empty strings can already be built in const without push (#698 and #701 make that possible). What's missing is reading them, which matters when the code that checks a value isn't the code that writes it. Of course, if you create the value yourself then you already know the length, but in my use case that's not the case, the values are written by users of my type.

Simplified usecase:
I validate at compile time values my users write.

pub struct Name(String<32>);

impl Name {
    pub const fn new(s: String<32>) -> Self {
        assert!(s.len() >= 3);
        Name(s)
    }
}

// Written by a user of `Name`, possibly in another crate:
pub const DEFAULT: Name = Name::new(String::try_from_str("sensor").unwrap());

Today s.len() fails in const, because it goes through Deref. (The real code is more complex, but this shows the gist.)

I'm also working on const as_str and others, so these checks can look at the contents too (e.g. allowed characters). This first step is a requirement for that.

Regarding the new unsafe block: it is very close to the already existing as_len_type, which is as_usize's inverse. They live next to each other too.

What do you think?

@sgued sgued reopened this Nov 7, 2026
@sgued

sgued commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

That's a decent use case. I'll look into it.

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.

3 participants