Cabal is not buggy. Or, more precisely, Cabal Hell is not the result of bugs in cabal. It is the result of 1) static linking with cross-module inlining, 2) a lot of diamond dependencies, and 3) a lot of breaking changes in the ecosystem.
1 is arguably an artifact of Haskell - performance really suffers if you can't do this - but also something that's arguably desirable generally.
2 is the result of the ability to provide abstractions and tools that are useful in a phenomenal number of contexts (mostly a good thing) and the failure of the language-as-standardized to provide these directly (mostly a bad thing).
3 is the consequence of an active community that values experimentation, is willing to try new things, and places an emphasis on Getting It Right. This is actually more mixed a blessing than it sounds.