Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting away lifetime constraints?

Tags:

rust

lifetime

I'm trying to write a Rust function that casts an input from one lifetime constraint to a same-typed output with a global lifetime constraint (conceptually something like unsafe fn foo<'a, T1, T2>(x: T1) -> T2 where T1: 'a, T2 = T1 + 'static), but I can't quite figure out how to write it without adding indirection layers like Box. Any ideas?

More generally, I'm trying to implement an unsafe thread::scoped in terms of mem::transmute and thread::spawn. spawn requires 'static bounds on its T and F parameters, but scoped does/should not.

like image 617
bfops Avatar asked Jun 27 '15 14:06

bfops


2 Answers

Although I had a similar problem, I do not recommend extending lifetime constraints. It's almost certain that a different approach is in order for situations where this comes up.

That said, you can extend a lifetime in the latest Rust stable (1.29.0 as of this writing) via std::mem::transmute.

Example from the docs (with the caveat "This is advanced, very unsafe Rust!"):

struct R<'a>(&'a i32);
unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
    std::mem::transmute::<R<'b>, R<'static>>(r)
}
like image 112
nfrasser Avatar answered Nov 12 '22 20:11

nfrasser


What you are describing now is simply not possible. A type satisfies a certain lifetime requirement, which is known statically. There can be no transmutation or such things between them. For the concept of your T2 to exist, T1 must be 'static already. What you seem to be trying to implement is flatly impossible and always will be.

It is possible to implement scoped using unsafe code, but it is not possible to implement it in terms of thread::spawn. You can take a look at the source code of thread::scoped in Rust 1.3.0 to see how this was done. Be aware that thread::scoped was removed because it had soundness issues, so it isn't a perfect example to copy wholesale.

like image 2
2 revs Avatar answered Nov 12 '22 21:11

2 revs