I don't think thank shrinking or keeping the same size may fail: if a better location can't be used (because the memory pool where it would fit can't be augmented or modified, the best thing to do is to keep the existing pointer, and just mark the end as "supposedly" unused (even if that unused part is not reallocatable for something else as that part would need to be added in a free pool.
The interface allows recording the effective size that is used in an allocated block, so that the end of block may or may not be reused later (immediately or not, when it will be possible to add the free part in a free pool, which may occur later when possible and where there will be an opportunity to do it).
Moving blocks when shrinking or redefining its size is allowed to move it, but is not forced to do it or to make a real deallocation immediately: the reported available free size may not change immediately.
But returning NULL for shrinking an allocated block or setting it to the same size is a non-sense that would cause more problems than what it would attempt to solve.