In Rust if you have a &Thing right here, you can't give that to some new thread unless you can promise the thread has a shorter lifespan than the &Thing does - otherwise the thread could access it after it ceases to exist, and you've introduced Undefined Behaviour.
Without scoped threads this means all references you want to give to a thread must be allowed to live forever, the lifetime 'static, since your threads might live forever (the mechanism to kill them could be discarded unused somehow). Since scoped threads always cease to exist when they go out of scope, we can give them references that live any time longer than that scope.
The important part is it safely allows you to pass references or other objects with lifetimes to those threads. (Or at least lets the compiler know so you can avoid having to write unsafe things yourself.)
This happened to be useful for something I was doing at work where the wrapper for a native C library expressed the required lifetimes of the library constructs using lifetimes. (Eg. You must set up Foo before Bar, and Foo must outlive Bar. It was OK to pass Bar and use it from multiple threads, but it had a lifetime attached. Using scoped threads we can satisfy the compiler's lifetime checker, since it knows even though we gave Bar to many threads, none of them outlive Foo.)
It's a building block allowing more threading abstractions to be build on top of it without using unsafe code.
Most importantly it works with references like `&`,`&mut` or `Cow` etc.
E.g. in the example below it use used to ad-hoc implemet a typical simple parallel fold
pattern where a collection of data points is chunked and split across num_cpu
threads where each chunk is processed in parallel followed by combining the results.
Now in practice for many use cases you want to use more convenient/optimized libraries like rayon for this kinda of things instead of ad-hoc implementing them by hand.
But having the necessary primitives to implement it ad-hoc yourself without unsafe code is grate anyway.
Doing this using a destructor, or worse in straight-line code, turns out to be unsound. So it's more than marginally useful for those familiar with Chesterton's fence.
I didn't say it was useless, only that its use is highly limited to a very specific case, namely "do a bunch of things at the same time and block until completion".
This is the point of lifetimes.
Everything has a lifetime whether or not it is annotated. Sometimes the compiler doesn't know what the lifetime of an object is, particularly in relation to other objects.
If you can scope something to main() then that is a 'static lifetime and there is no need for a scoped thread for it.