Is it possible to use &'static via std::mem::transmute, given that the data referenced by 'static exists longer (forever)? Will this lead to some error? I need this for working with tokio. I'm trying to work with 'a, but it only leads to errors.
You're probably referring to spawn() forbidding temporary references.
Generally it's unsafe (for real, not just in theory) to extend some 'a lifetime to 'static. You should use Arc or move data inside the spawned future. The spawned future could outlive the context that is lending it references, leading to use-after-free vulnerabilities. You could also violate aliasing rules (which is UB), because a shorter lifetime doesn't give you any guarantee it will stay immutable or exclusive for your use after the end of the shorter lifetime.
When the Rust compiler tells you to use &'static, it's actually just a bad error message. It doesn't want you to use that type. What it is actually trying to say is that all temporary references are forbidden in that context.
Box::leak can create &'static borrows https://doc.rust-lang.org/std/boxed/struct.Box.html#method.leak
But not recommend, you'd better use another way to implement your feature.
&'static means your object won't be dropped until the program exit, it will cause memory leak.
You may need Arc if you want to send the shared data into an async scope
But my code already works with &'static, I'm just worried it might trigger UB, despite the fact that data lives longer than references. That is, the code received the data, created a &'static for it to avoid ownership issues, used and deleted the &'static, the data continues to exist.
Thanks, I was thinking about that too, but Box and Arc cause allocation, which is unacceptable according to the requirements.
If your code is used to initialize things, allocations are ok
This is my personal opinion, I haven't touched unsafe codes
Unfortunately, this happens after code initialization. In short, this is a zero-alloc HTTP parser. Data is stored in &'static, which is destroyed after use, and the buffer referenced by &'static is simply overwritten with zeros and continues to exist.
I want to find out whether this code can cause any error during operation or not.
You could try miri
Install it by running
rustup +nightly component add miri
Use this to test your application
cargo +nightly miri run
If you already have actual references that are compatible with &'static, then it won't be UB, and the code should just compile without hacks.
But if you have to transmute, then whether it's really UB depends on what do you do with it, and what type it is.
-
Any
&'static T(outside of interior mutability) must be strictly immutable. Memory still existing, but being written to when borrowed as&'staticis UB. If you create a mutable&'static mut, then you must guarantee there it can't be accessed from anywhere else, and there won't be another reference created to this memory (creating a mutable aliasing reference is instant UB, even if not dereferenced). -
If you take some
'aand cast it to'static, the borrow checker won't be able to verify correctness of it. AFAIK this isn't immediate UB, but depends on what actually happens, like with unsafe pointers (if you don't cause invalid aliasing, and can stop using the reference before it's invalidated, it may be ok). InFutures, you have to consider that futures can be cancelled at any.awaitpoint, which generally makes casting of'ato'staticunsound and potentially use-after-free UB, because the future you got the data from can be cancelled and dropped while yourspawn()ed task is running (or even before it starts running).
It shouldn't be necessary to transmute:
-
Box::leakis safe, and gives you&'static mut. You shouldn't needtransmutefor stuff on the heap. You need the heap to safely get exclusive&'static mut, otherwise you get only shared&'static. -
static VAR+LazyLockcan give you&'static Tin safe code, but you can write to it only once. -
if you need to zero out the data later, then I don't know if you can do better than
&'static [Atomic*]or&'static Mutex<Option<T>>. -
If you have generic code using
'a, then change it to'static. Sometimes you don't even need to change the definition, but can changeimpl, e.g.impl Trait for Type<'static>orimpl Trait<'static> for Typedepending how things are defined.
Thank you very much for the detailed answer! Indeed, the data remains unchanged from the moment &'static is created until it's deleted. Unfortunately, there is no talk of removing transmute yet; I've tried, but to no avail. In any case, thank you very much for your answer; it's been very helpful! I'll keep this in mind for future design decisions.