The core language is fine, but when you actually start building things you need to introduce lifetimes, all the traits that you polluted your interface with and then add on async, it gets out-of-hand quickly.
The top comment gave a perfect example: #![feature(strict_provenance)]
These feature enablement blocks drive me crazy. You could go from codebase to codebase and it's almost like you are working in a different language depending on how many of these are enabled or not. I've been trying rust on and off since it's release, and I still have yet to feel like I have a grasp on some "core" subset of the language I can fall back on to solve most of my problems. I always have to scour documentation for the hot new thing to turn on or do, and this isn't to scorn innovation and change, but it does get exhausting at some point.
A spec is not a replacement for #![feature] attributes. It's rather the opposite: #![feature] indicates that you are stepping out of the stable, specified core language and into an area that is still a work in progress and thus cannot have a committed specification yet. You shouldn't need it at all unless you are actively experimenting with some unfinished proposal.
Those feature blocks exist only for nightly/unstable Rust. You don't have those on stable Rust. The most you might have are derive blocks but those just automate what you'd write by hand anyway.
These feature enablement blocks drive me crazy. You could go from codebase to codebase and it's almost like you are working in a different language depending on how many of these are enabled or not. I've been trying rust on and off since it's release, and I still have yet to feel like I have a grasp on some "core" subset of the language I can fall back on to solve most of my problems. I always have to scour documentation for the hot new thing to turn on or do, and this isn't to scorn innovation and change, but it does get exhausting at some point.
(Please release a spec)