top | item 41398654

(no title)

jiwangcdi | 1 year ago

> The next noisy element is the <P: AsRef<Path>> constraint. It is needed because Rust loves exposing physical layout of bytes in memory as an interface, specifically for cases where that brings performance. In particular, the meaning of Path is not that it is some abstract representation of a file path, but that it is just literally a bunch of contiguous bytes in memory.

I can't understand this. Isn't this for polymorphism like what we do this:

```rust fn some_function(a: impl ToString) -> String { a.to_string(); } ```

What to do with memory layout? Thanks for any explanation.

discuss

order

K0nserv|1 year 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|1 year ago

Then if Path is not about abstraction, why not use a raw byte slice like &[u8]