What is wrong with auto .into?

That won't work. Macros work at the level of well-formed Rust tokens, and all brackets must always be balanced. You can't preserve whitespace within a string with such macros, spaces and carriage returns will be removed and added in arbitrary ways. Anything which looks like a comment will be stripped entirely, and plenty of things cannot be parsed at all.

Yeah, my fault. Still can use this (I edited post) tho

If String literals are ever added, it's going to be a suffix not a prefix, like "abc"s. The language syntax already allows such literals with custom suffixes, there is just no way yet to specify their meaning.

&s"666" is supposed to be a shared reference to a String. However, its content is immutable and deterministic at compile time, so I think the compiler can optimize it to eliminate the allocation.

I have no objection on this. Fair enough to me.

I think this falls under the "heap allocations in constants" proposal

1 Like

Furthermore, I would like to say that it would be better to have proc_macro supported suffixes like

const pattern: Regex = "[regex].*"r;

It is much better than currently OnceCell based solutions.

since the former can be generated at compile time.

AFAIK, arbitrary prefixes have been made a reserved syntax, in part specifically for future String literals: Stabilize reserved prefixes · Issue #88140 · rust-lang/rust · GitHub

2 Likes

I'd just expect clippy to say something about unnecessary String as I'm not sure how such a transform would work with the "as-if" rule if there's a way to transmute that &str into a &String (all ways may well be UB, but I'm not sure).

You can't turn &str into &String, because (very very roughly) String is Box<str>, so there's a level of indirection you can't undo.

If the constant is &String and not &str, though, there's probably no way to replace it with a reference to constant data.

Ok, that sounds like a valid "as-if" optimization. But I think it's better done by clippy because it's just confusing otherwise.

To be clear: I agree.

Even if/when we get (global) allocation in const, I very highly expect that any attempt to "leak" those allocations to runtime to be forbidden for a very long time. IIUC that's the way C++ constexpr allocation works; any constexpr new must be constexpr deleted by the end of the consteval scope, or the program is ill-formed (diagnostic required).

The main problem is that allocations are actually shared mutability, and shared mutability in const (or static) is problematic; at best, it's a footgun, and at worst it's UB (attempting to write to constant memory).

This can be relaxed if and only if the memory is known to be shared, not contain any shared mutability, and there be no remaining-at-runtime way to get (potentially shared) mutable access to any of the memory. In Miri and Stacked Borrows, this IIUC corresponds to all accessible memory being tagged as Shared and any tag other than the top Shared tag not being stored in any provenance. This is a checkable, but somewhat complex condition.

If the relaxation is desirable, the only relaxation we get may be the ability to Box::leak an allocation and expose a shared reference to the leaked allocation if the allocation itself does not contain any shared mutability nor any other allocations. In code, that'd be e.g.

const _: &str = Box::leak(s"".into_boxed_str());

Allowing anything more than that is at best an open research question on how to verify and guarantee that serving the allocation requests as static readonly memory is acceptable.

1 Like

Just curious, when turn a str to String, why not do a lazy allocation. I believe a lazy allocation can avoid 80% of the allocation. Since most of the time, the string will not be changed anyway.

That's called Cow<str>, so that String doesn't penalize people who don't need the laziness checks.

This is simply wrong! String should support this silently. We need to lower the burden of developers

1 Like

It is already bad enough to have str and String, now you have cow? Needless to mention the os_str and other weird stuff

One problem with this is that keeping a reference to the original str would prevent changing or dropping it for as long as the String lives.

A const str will never be dropped.

I actually mean only the const literal str.

Isn't this in contrast to Rust's goal of making things explicit?