That is not true. If you can demonstrate that every loop or recursion is bounded, then the program must halt as a necessity. Loops of the form for (i = 0; i < N; i++) are trivially bounded, unless you're resetting i in the loop. If you have containers that are not being modified in the loop, the finiteness of your data structures is usually sufficient to form the lemma that the loop will terminate.
Recursive datastructures (such as cyclic graphs) are much more challenging to prove, and most challenging are fixed point algorithms (do { } while (changed);), as will be noted by them frequently being the causes of actual infinite loops in my experience. But if you had mandatory annotations to declare lemmas for termination, it is doable. With that feature, a programming environment that forbade you from writing code that couldn't be proven to terminate is probably sufficiently feasible to allow you to write large, complex applications.