I'll be honest. I've written async code in Rust for years and I don't think I've used select at all. I tend to drop into manually implementing Future
before that point. Either way, the issues related to that macro still exist, but the author seemed to call it out and link to an article about it (which doesn't seem disingenuous at all to me).
As for cancellation, the fact that you can cancel tasks by default in Rust has come up far more for me than any issues with unintended cancellation (which I don't remember ever coming up, honestly). What I find myself wanting in other languages (especially JS) is the ability to both control when the task starts executing (for initialization logic or to prepare the task and pass it somewhere before it starts executing) and when it stops executing (early termination, for example with debouncing). I don't get that by default in other languages, or often even at all in JS (unless I pass an abort controller everywhere).
Don't forget Intel's latest GPU launches either! For custom PCs, there are some really affordable and relatively powerful GPUs available now (for the price). Despite their performance otherwise, Intel is killing it in the GPU space now.
For a lower spec build, you could definitely put together something with a 12100F (or other cheap CPU) and a battlemage GPU. Depending on where you get all the parts, you might be able to hit sub-$500 and get great 1080p performance, or for sure sub-$1k 1080p and likely 1440p performance.
Handhelds also have a lot of good options available too. To save some cash, you can get low end Steam Deck and swap the hard drive yourself. Got myself the cheapest LCD variant and swapped the tiny drive in it with a 2TB drive off Amazon.