Search code examples
rustfile-ionested-function

Why does std::fs::write(...) use an inner function?


I'm new to Rust and have been looking through the source code a bit, and found this:

#[stable(feature = "fs_read_write_bytes", since = "1.26.0")]
pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> {
    fn inner(path: &Path, contents: &[u8]) -> io::Result<()> {
        File::create(path)?.write_all(contents)
    }
    inner(path.as_ref(), contents.as_ref())
}

Is there any reason this function defines an inner function like this? Why not just write:

File::create(path.as_ref())?.write_all(contents.as_ref())

Solution

  • Monomorphization costs.

    write(), like most filesystem functions in Rust, takes AsRef<Path> instead of Path, for convenience (to allow you to pass e.g. a &str). But that also has a cost: it means that the function will be monomorphized and optimized separately for each type, while there is no real need for that. While it is very likely that LLVM will deduplicate all those instances, the time used for optimizing them is still wasted compile time.

    To mitigate this cost, it calls an inner, non-generic function that does all the heavy lifting. The outer function contains only the necessarily-generic code - the conversion to Path.