Refactor slice pattern usefulness checking
As a follow up to https://github.com/rust-lang/rust/pull/65874, this PR changes how variable-length slice patterns are handled in usefulness checking. The objectives are: cleaning up that code to make it easier to understand, and paving the way to handling fixed-length slices more cleverly too, for https://github.com/rust-lang/rust/issues/53820.
Before this, variable-length slice patterns were eagerly expanded into a union of fixed-length slices. Now they have their own special constructor, which allows expanding them a bit more lazily.
As a nice side-effect, this improves diagnostics.
This PR shows a slight performance improvement, mostly due to https://github.com/rust-lang/rust/pull/66129/commits/
149792b6080f40875c0072aae378a0eb31d23df0. This will probably have to be reverted in some way when we implement or-patterns.