Bear with me if I missed this in documentation:
Assume I open a few files in a nim program, but never close them explicitly.
Do these get closed automatically - either when the variables holding the handles run out of scope or at the end of the program (in the sense of the nim compiler creating cleanup code taking care of such things), or does the failure to close them explicitely lead to a file handle leak?
Almost all C libraries will also flush the buffers in FILE (that is what the Nim File wraps) and then the OS itself reclaims file slots (if the C lib does not call the OS close which it probably does, but you can tell with "system call tracers").
If the OS did not reclaim then any user could break the whole system by just re-running some buggy program. It is basically job number 1 of OSes to protect sound programs from buggy ones. While they don't always succeed, this is a very easy case they would be unlikely to get wrong. So, "remotely safe OS" basically implies such clean-up of file handles/open files (amongst other resources).
You can make it yourself:
type
ScopedFile = distinct File
proc `=destroy`(x: var ScopedFile) =
close(File(x))
proc `=copy`*(dest: var ScopedFile; source: ScopedFile) {.error.}
proc main =
var f = ScopedFile(open("temp.txt", fmWrite))
File(f).write "Hello World\n"
main()