Refactor method dispatch infrastructure

This is a pretty major refactoring of the method dispatch infrastructure. It is intended to avoid gross inefficiencies and enable caching and other optimizations (e.g. #17995), though it itself doesn't seem to execute particularly faster yet. It also solves some cases where we were failing to resolve methods that we theoretically should have succeeded with.

Fixes #18674.

cc #18208 


Coercion/cast rules are changing, and this is a weird psuedo-ambiguous case. That is, slices will cast to both `*const [T]` and `*const T`. Might want to disambiguate here. Might also just want to test that xptr.foo() and xsliceptr.foo() both work, in case there's a symmetry issue.