Why can I call a mutable method from a non-mutable reference?

I have stumbled upon code similar to this one and it leaves me pretty confused:

use std::fs::File;
use std::io::{self, Write};

struct Foo {
    file: File,

impl Foo {
    fn bypass_nonmut(&self, data: &[u8]) -> io::Result<usize> {

std::io::Write.write() takes a mutable reference to self. My method bypass_nonmmut() only provides a non-mutable reference to the object owning the File instance, which should make it impossible to call write() on it. Yet using the (&self.file) trick I can call it regardless.

Could someone explain to me how this is possible?

1 Like

There is an implementation of Write for &File, which is what's being used by your method.

1 Like

Rust references are primarily about being shared vs exclusive.

Mutability is only a secondary effect (&mut isn't a great name because of that, it should have been something like &excl). For example, atomic numbers can be mutated via shared reference. Types with interior mutability can be mutated via shared reference. &File can be written to, because the OS supports shared access.


Ahhh that makes sense. Files are safe to access concurrently, so there is no reason to limit their access to be unique. The Write and Read interfaces mandate a unique reference, but implementing them on &File provides a way to perform concurrent access anyway through a zero-cost indirection.

Thanks for the explanation, I can sleep tonight!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.