4 ms·
Rust needs to know the exact size, layout, and alignment of every argument passed to a function to determine how it gets passed(register(s) or spilled to stack)
by K0nserv 2y ago
Rust needs to know the exact size, layout, and alignment of every argument passed to a function to determine how it gets passed(register(s) or spilled to stack) and used. For example PathBuf and String can both be turned into a reference to a Path, and while they have the same size their layout and implementation of `as_ref` differ.
As for `impl`,
fn foo(a: impl ToString)
is syntactic sugar for
fn foo<S: ToString>(a: S)
The reason the standard library doesn't use this is because the code predates the introduction of `impl` in argument position.
The reason the function takes `AsRef<Path>` instead of `&Path` is callsite ergonomics. If it took `&Path` all callsites need to be turned into `read(path.as_ref())` or equivalent. With `AsRef<Path>` it transparently works with any type that can be turned into a `&Path` including `&Path` itself.
- jiwangcdi 2y agoThen if Path is not about abstraction, why not use a raw byte slice like &[u8]
- K0nserv 2y agoThat's orthogonal. If the type was `&[u8]` instead of `Path` the type signature would be: pub fn read<P: AsRef<[u8]>>(path: P) -> Result<Vec<u8>> The reasons for it to be generic and us `AsRef` remain. The reason for Path over &[u8] is, AFAIK, because not all byte slices are valid paths on all OSs, but also because a dedicated type lets the standard library add methods such as `Path::join`
- jiwangcdi 2y agoSo abstraction is still a point, but Rust cares about memory layout as well.
- K0nserv 2y agoSort of, this API enables static dispatch, but it could also have been written as pub fn read<P: AsRef<Path>>(path: &dyn P) -> Result<Vec<u8>> In which case the size of `path` is always the same(two words[0]) and the same machine code could be used regardless of how the function is called. Rust still cares about the memory layout but because `&dyn AsRef<Path>` has the same layout for all implementations of `AsRef<Path>` there's no need for monomorphization[1]. 0: https://doc.rust-lang.org/1.80.1/reference/types/trait-object.html https://doc.rust-lang.org/1.80.1/reference/types/trait-objec... 1: https://rustc-dev-guide.rust-lang.org/backend/monomorph.html#monomorphization https://rustc-dev-guide.rust-lang.org/backend/monomorph.html...