Change:
This issue is for tracking the feature (PR ). The feature adds an unsafe method to called , which allows spawning a thread without restrictions on the lifetimes of either the supplied closure or its return type. The method is unsafe because the caller has to guarantee that the spawned thread is explicitely joined before any referenced data is dropped. The main use for this feature is as building block for libraries that build safe abstractions around it, such as scoped threads. Currently such libraries have to rely on subversions of the type system/borrow checker.
what do you think about changing to This removes the burden of dealing with lifetime fumbling from the native implementations to where the unsafety is actually introduced.
I'm sorry but I fail to see what this would accomplish, could you explain further?
Context: I'm running into issues implementing a new target in after your recent chanages. Previously, the implementation was approximately this: such that the in could take a (implied static bound). Now, you have which requires the in takes a . However, since native threading APIs don't have a notion of lifetimes, this requires the implementation code to think about what to do with this lifetime , which probably just ends up getting converted to or such. Since already documents this behavior as part of its unsafe API (“The caller has to ensure that no references in the supplied thread closure or its return type can outlive the spawned thread's lifetime.”) I think it makes sense to pass on the most liberal lifetime possible () to the underlying native implementation. If this is all too vague, happy to ping you about this again when my new target PR is ready.
It seems to me that you have some misconceptions about lifetimes. This seems to be at the core of it, as the lifetime is in fact quite the opposite: It is the most restrictive lifetime bound possible (this of the Rustonomicon contains some clarifications on the topic IIRC). A completely unbounded lifetime like is the most lenient bound (or non-bound) that can be applied to a type or a trait. You are correct that native thread implementations have no notion of lifetimes, which is precisely why it makes sense to not bound lifetimes in any way, which is why the bounds for and are the way they are. The lifetime bound is just tacked on later by the Rust implementation in order to achieve memory safety. I hope this explanations of the way I understand it makes sense to you.
Most lenient from the perspective of the caller. I'm talking about the perspective of the callee. A function receiving can basically do absolutely nothing with that closure besides calling it right away. It certainly can't send it to another thread.
Is there anything blocking this from stablization?
Is there anything I can do to help this along to get stabilized? In my opinion the addition is straight forward, as it doesn't really alter the previous implementation and just exposes an intermediate step. I have also laid out the safety concerns in the new unsafe function quite clearly I think. If it helps, is a link to a small demonstration how this function could be used to build a safe scoped thread abstraction that uses very little unsafe code (less than the current crossbeam implementation, which has to do lifetime transmutations).
Bumping again, would like to see this stabilized.
Would it make sense to also remove the requirement? As the name says, this is unchecked and unsafe anyways.
I don't think so because it is never fine to send things to another thread, and if you are determined to do so, you can implement for a wrapper type , and use that.
That is not correct, consider the following example: is but in this example it is sound (but pointless) to send it to a thread, since the reference is not actually shared. Even if it were cloned and the clone sent into the thread there would be no issue as long as the reference in the main thread were dropped only after the join. So I'd think it might be ok to remove the requirement for . As a consequence, this would make it using this function in application code less desirable (one more invariant that has to be checked), which is probably something that would be considered to be a plus by most (keeping people from using whenever possible) and move this function firmly into the realm of (internally unsafe) library territory.
Ok, I'll adjust my statement. We already have an easy way to implement with (just ), so we don't need to remove the bound from . Keeping the bound will make checking a bit easier because you don't have to worry about accidentally sending data. tldr: keeping the bound makes things more orthogonal, and easier to check
Hello ! Any blockers for stabilisation ? Thanks a lot
Hello all, any updates on this?
Per , here's a ping to (found ) to see if this is ready for stabilization. I (on behalf of Adobe) need this stabilized for a concurrency library I'm developing.
fcp merge Example of correct usage, adapted from Alternatives:
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [ ] [x] [x] [ ] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
:bell: This is now entering its final comment period, as per the . :bell:
The signature of has a lifetime which seems entirely unnecessary and should be removed.
Lifetime cleanup:
The final comment period, with a disposition to merge, as per the , is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon.

Discussion:
// tidy-alphabetical-start #![feature(decl_macro)] #![feature(let_chains)] <del> #![feature(thread_spawn_unchecked)] </del> #![feature(try_blocks)] // tidy-alphabetical-end

/// # Examples /// /// ``` <del> /// #![feature(thread_spawn_unchecked)] </del> /// use std::thread; /// /// let builder = thread::Builder::new();

/// ``` /// /// [`io::Result`]: crate::io::Result <del> #[unstable(feature = "thread_spawn_unchecked", issue = "55132")] </del> <ins> #[stable(feature = "thread_spawn_unchecked", since = "CURRENT_RUSTC_VERSION")] </ins> pub unsafe fn spawn_unchecked<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where F: FnOnce() -> T,