But to say the gap in safety is very small is essentially to say Rust's lifetime system is close to zero-value.
Unsafe code still exists, the goal is to localize it to small, auditable blocks. However safety often depends on non-local properties. For example, unchecked iteration over a vector requires we know the vector's lifetime exceeds the iteration lifetime, and that the backing buffer won't change. Rust's lifetime system allows this to be expressed, so the "critical zone" can be localized within a single block in the library implementation. If the library is correct, all consumers are safe. In C++, these cannot be expressed, so the critical zone for this safety guarantee is smeared across all code executed during the iteration. No consumer is guaranteed safe.