I think this is just because the returned slice doesn't necessarily have the same size as new_layout specified, so the function needs to return a length, and putting it in a fat pointer is an easy, unambiguous way to do it.
Forcing the callers to construct a slice pointer in order to specify a specific length would be redundant (and add a need for additional checks -- what if the slice length and old_layout were incompatible?).
Also, returning the length allows, for example, a Vec implementation to take advantage of the excess memory returned by calculating a larger capacity than requested.
And then the leniency of "fitting" allows, for example, the Vec to just use that larger capacity to create old_layout when growing in the future, instead of having to remember either the requested layout or the returned length from last time.