libsyntax/parse: avoid reading directories as files on *BSD

On *BSD systems, we can `open(2)` a directory and directly `read(2)` from it due to an old tradition.  We should avoid doing so by explicitly calling `fstat(2)` to check the type of the opened file.

To do so, it was necessary to elide unnecessary mutability of `&self` in `io::fs::File::stat()`.

Opening a directory as a module file can't always be avoided.  Even when there's no "path" attribute trick involved, a *directory* can always be named as `my_module.rs`.

Incidentally, elide unnecessary `Path::clone()` in libsyntax.
We typically try to not house logic such as this in the compiler itself but rather put it in the standard library. As `std::io::File` is a cross-platform abstraction and we generally try to enforce the same behavior across platforms. If `read_to_end()` is only available on freebsd/dragonfly, I'd personally be a little more in favor of putting the error all the way over into `std::io`.

Exposing the platform-specific behavior will be done through `std::sys` in time as we expose the raw underlying system primitives for this sort of operation.