There's value to being opinionated about API design, but there's also cost. And Rust is supposed to be playing in the same sandbox as the lower level tools.
There's value to being opinionated about API design, but there's also cost. And Rust is supposed to be playing in the same sandbox as the lower level tools.
I don’t think either of those is true. Encoding the ownership in the type system makes things clearer, imposes a compile-time cost but not run-time cost. Also, there isn’t any magic in the stdlib implementation of Mutex and Rwlock other than implementing it natively for every OS. This means that it is possible to implement the pattern for the examples you gave.
Idiomatically, you would then make `Foo::new_unchecked()` unsafe, with the precondition that nobody else is accessing the same external resource, and that `Foo::new_unchecked()` is only ever called once.
So long as MacGuffin doesn't have any data in it, it essentially evaporates at runtime. This is a zero size type (ZST) so we can store that in no bytes of RAM, we can use no registers at all to pass it into a function, and so on. If you're a C programmer this doesn't make sense because you don't have ZSTs, all your types take up at least one byte, but Rust isn't like that.
If locking and unlocking semantics are a good fit for whatever you are doing, then you can just do a lock implementation setting whatever memory mapped registers you need. There is no constraint here whatsoever.
Nobody is advocating for separate atomics in every little object in Rust. That's a Java idea that failed miserably long before Rust was even around.