Limited Opt Out of Orphan Rule

Concrete example of your first case: I have a project right now that uses rustix and unix_path in a no-std context. (It's a fully hosted environment; no-std is only being used to avoid a dependency on the C runtime.) Because rustix and unix_path are independent crates, neither of them provides an impl of rustix::path::Arg for unix_path::UnixPath, and the orphan rule prevents me from providing one, which means I have to write path.as_unix_str().as_bytes() every time I want to pass a path to a rustix function, which is often.

(It's my impression that this sort of thing is the most important reason why people want to relax the orphan rule. I could work around this with a newtype over UnixPath, but getting its ergonomics to match UnixPath's would be more work than continuing to type path.as_unix_str().as_bytes() all over the place.)


This is not technically about the orphan rule, but it's a closely related possible language feature that would require us to solve many of the same problems: Sometimes a crate might wish to override the implementation of a trait by one of its dependencies. This same project provides a good example: In a no-std configuration, rustix's Display impl for rustix::io::Errno prints "os error <number>" for all errors, which is not exactly user friendly; I'd ideally like to override it with an impl that provides the usual human-readable error strings for at least the errno values that I expect to come up in normal operation. Again, this can be dealt with by using a wrapper struct, but at the expense of at least some ergonomics -- right now what I have is a local conversion trait that lets me write

writeln!(stderr, "failed to {}: {}", operation, err.msg())

when err is an Errno, which is not bad but not as nice as

writeln!(stderr, "failed to {operation}: {err}")
1 Like