Why does it say "We must not include limits.h!" in dirent.h?

Each standard header has a specification for what it exposes or may expose. dirent.h exposes struct dirent, DIR, and the relevant functions, and reserves names starting with d_. Some headers are also permitted but not required to expose things exposed by certain other headers; dirent.h is not one of these. So indirectly including limits.h would be a violation of the namespace and would break conforming programs that assume they can use names that limits.h would expose for their own identifiers.