# Alloc: Vec::as\_slice, String::as\_str -\> const

**URL:** <https://internals.rust-lang.org/t/alloc-vec-as-slice-string-as-str-const/20986>\
**Category:** libs\
**Created:** [June 7, 2024, 9:44am UTC](https://internals.rust-lang.org/t/alloc-vec-as-slice-string-as-str-const/20986 "2024-06-07T09:44:21Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![mammothbane](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mammothbane/32/1143_2.png) [@mammothbane](https://internals.rust-lang.org/u/mammothbane)\
**Post date:** [June 7, 2024, 9:44am UTC](https://internals.rust-lang.org/t/alloc-vec-as-slice-string-as-str-const/20986/1 "2024-06-07T09:44:22Z")

</div>

I'm writing a library that wants `Vec::as_slice` and `String::as_str` to be `const`-qualified -- the types I'm trying to produce are enums that _may_ contain either `Vec<T>` or `&[T]` (and similarly `String` or `&str`), and I'd like to be able to write a `const fn as_slice()` / `as_str()` for them.

Presently, this isn't possible because the stdlib functions I need aren't `const`, but logistically, changing them (or writing `_const`-suffixed versions) is trivial -- I've written a local liballoc patch to enable the functionality I'm looking for and tested it successfully with my library -- is this likely to be viewed favorably for upstreaming? Would a change like this require an RFC? Are there problems with this approach re: `const`-ness I haven't seen/understood?

> **Library motivation, for anyone interested**
>
> The library is in a similar spirit as [`managed`](https://docs.rs/managed/latest/managed/) (and `Cow`, in some sense) with the intent of abstracting static vs dynamic allocation of immutable data, supporting `#![no_std]` environments that may or may not have `alloc`. I have an enum `ImmutSlice<'t, T>` which can be `Slice(&'t [T])` or `Vec(Arc<Vec<T>>)` (plus `ImmutStr<'s>` for `Arc<String>`/`&'s str`).
> 
> I think the most concise way to put the idea is that the types _support_ upgrading to `'static` where required, by cloning the borrowed variant into `Arc`, but do not need to `leak()` to do so -- the allocation can be recovered when all references go out of scope.

---

<div class="post-metadata">

**Author:** ![pacak](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pacak/32/11934_2.png) [@pacak](https://internals.rust-lang.org/u/pacak)\
**Post date:** [June 7, 2024, 11:20am UTC](https://internals.rust-lang.org/t/alloc-vec-as-slice-string-as-str-const/20986/2 "2024-06-07T11:20:15Z")

</div>

Can you currently create a non-empty `Vec`/`String` as a `const`? For empty values you can use `&[]` and `""` respectively without helpers, but I'm not sure if non-empty ones are possible.

---

<div class="post-metadata">

**Author:** ![kpreid](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kpreid/32/8484_2.png) [@kpreid](https://internals.rust-lang.org/u/kpreid)\
**Post date:** [June 7, 2024, 3:28pm UTC](https://internals.rust-lang.org/t/alloc-vec-as-slice-string-as-str-const/20986/3 "2024-06-07T15:28:56Z")

</div>

> [@mammothbane](#):
>
> Presently, this isn't possible because the stdlib functions I need aren't `const`, but logistically, changing them (or writing `_const`-suffixed versions) is trivial -- I've written a local liballoc patch to enable the functionality I'm looking for and tested it successfully with my library -- is this likely to be viewed favorably for upstreaming?

The only reason to keep a function not `const` is if in the future it might need to do something that _can’t_ be `const`. That seems unlikely for the ones you named, so I’d say go for it.

> [@mammothbane](#):
>
> Would a change like this require an RFC?

No, but to be _stably_ const it will need approval from T-libs-api — which can happen on the PR that makes the change, so you don't need to do anything special.

I'm not sure whether it would be required to be unstable const before stabilization; presumably yes but I'm not familiar with the design principles in that area.

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [June 7, 2024, 4:43pm UTC](https://internals.rust-lang.org/t/alloc-vec-as-slice-string-as-str-const/20986/4 "2024-06-07T16:43:47Z")

</div>

> [@kpreid](#):
>
> I'm not sure whether it would be required to be unstable const before stabilization; presumably yes but I'm not familiar with the design principles in that area.

Something as trivial/uncontroversial as this could be done without being unstable imo. Not a team member, though.

---

<div class="post-metadata">

**Author:** ![pitaj](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pitaj/32/11262_2.png) [@pitaj](https://internals.rust-lang.org/u/pitaj)\
**Post date:** [June 7, 2024, 5:05pm UTC](https://internals.rust-lang.org/t/alloc-vec-as-slice-string-as-str-const/20986/5 "2024-06-07T17:05:41Z")

</div>

I'm not opposed, but I also don't really understand the use case here. How are these useful in const contexts?

---

<div class="post-metadata">

**Author:** ![SkiFire13](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/skifire13/32/7579_2.png) [@SkiFire13](https://internals.rust-lang.org/u/SkiFire13)\
**Post date:** [June 7, 2024, 5:25pm UTC](https://internals.rust-lang.org/t/alloc-vec-as-slice-string-as-str-const/20986/6 "2024-06-07T17:25:05Z")

</div>

I don't think this would play well with the [Store API RFC](https://github.com/rust-lang/rfcs/pull/3446). Under that proposal `as_slice` would have to `resolve` the handle, but that's a trait method and at least for a while they won't be able to be `const` (and even then, not all `resolve`s might be `const`s).

---

<div class="post-metadata">

**Author:** ![kpreid](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kpreid/32/8484_2.png) [@kpreid](https://internals.rust-lang.org/u/kpreid)\
**Post date:** [June 7, 2024, 5:35pm UTC](https://internals.rust-lang.org/t/alloc-vec-as-slice-string-as-str-const/20986/7 "2024-06-07T17:35:18Z")

</div>

> [@pitaj](#):
>
> I'm not opposed, but I also don't really understand the use case here. How are these useful in const contexts?

This code doesn't compile, but it would if `String::len()` was a const fn:

```rust
use std::borrow::Cow;
const fn length(s: &Cow<'_, str>) -> usize {
    match s {
        Cow::Borrowed(s) => s.len(),
        Cow::Owned(s) => s.len(),
    }
}

```

So, making these functions `const` allows writing functions that can be used in const evaluation on `enum`s that may contain run-time-only values, but of course won't _actually_ contain them at compile time.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [June 7, 2024, 6:31pm UTC](https://internals.rust-lang.org/t/alloc-vec-as-slice-string-as-str-const/20986/8 "2024-06-07T18:31:16Z")

</div>

In general, if both

1. You can make it `const` without changing the implementation (no rewriting `for` loops, for example), and
2. There are ways to actually make the arguments in `const`

then you can just send a PR making it unstably const and it'll get signed-off on easily.

Making it _stable_ for const is a harder question, but one that can be deferred a bit.

* * *

The why for those two cases are basically their contrapositives:

1. We decided to stop making the implementation ugly just to support `const`. As such, we're usually waiting on things like `impl const` before making things that depend on traits be `const`.
2. We don't want PRs for every single function that could possibly be marked `const`, since that's just noise if the `const`-ness wouldn't ever be useful for anyone.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [September 5, 2024, 6:31pm UTC](https://internals.rust-lang.org/t/alloc-vec-as-slice-string-as-str-const/20986/9 "2024-09-05T18:31:25Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
