Some thoughts:
1. Most of the superficial changes, like 'dyn' and Rust 2018, are easily handled using automatic tools.
2. The original Rust 'Error' trait was clunky, and it lacked useful features like backtrace support. This led to a series of experiments and fads in error handling (e.g., error-chain, failure), which are only starting to calm down after recent enhancements to 'Error'. More conservative Rust users avoided this by sticking with 'Error' and living with the limitations.
3. Updating depencies has been surprisingly easy, with several notable exceptions. Very early adopters of 'tokio' 0.1 had a fair bit of work to do once 'async' stabilized. And OpenSSL has been a constant thorn in my side, despite being a native C dependency.
One handy tip: Don't force yourself to constantly update your code to use all the latest features. Not everything needs to be async. And it's OK to have some rarely-touched modules that are written like it's 2015.