See #19915. Also implements #16989. Fixes #8318.
There are still several TODOs, and lots of missing documentation and tests. But it's coming along. Let's see what CI thinks so far.