Skip to content

Borrow checker thinks self is not mutable, when it is. #106325

Closed
@Nordgaren

Description

@Nordgaren

I am trying to extend ByteOrder + Seek, and I have two traits, right now. The first is just extending ByteOrder, and the second extends ByteOrder + Seek

pub trait BinaryReader: ReadBytesExt {
     fn read_bytes(&mut self, size: usize) -> std::io::Result<Vec<u8>> {
        let mut buf = vec![0u8; size];
        self.read_exact(&mut buf[..])?;
        Ok(buf)
    }
    
    //other methods
}

impl<R: ReadBytesExt> BinaryReader for R {}

pub trait BinaryPeeker: ReadBytesExt + Seek {
   fn peek_bytes(&mut self, size: usize, position: u64) -> std::io::Result<Vec<u8>> {
        let start = self.stream_position()?;
        self.seek(SeekFrom::Start(position))?;
        let bytes = self.read_bytes(size);
        self.seek(SeekFrom::Start(start))?;
        return bytes;
    }
    
    //other methods
}

For some reason, I get this error when compiling, and it only occurs on the line with read_bytes.

  --> src\binary_reader.rs:60:21
   |
60 |         let bytes = self.read_bytes(size);
   |                     ^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable

There are two ways I can work around this, for now. One is by copying the read_bytes method into the other trait, which I don't really wanna do, or I found this goofy code will also work...

    fn peek_bytes(&mut self, size: usize, position: u64) -> std::io::Result<Vec<u8>> {
        let mut s = self;
        let start = s.stream_position()?;
        s.seek(SeekFrom::Start(position))?;
        let bytes = s.read_bytes(size);
        s.seek(SeekFrom::Start(start))?;
        return bytes;
    }

Hopefully this helps clue you in on what is going on.

Is this a bug with the borrow checker?

Meta

rustc --version --verbose:

rustc 1.66.0 (69f9c33d7 2022-12-12)
binary: rustc
commit-hash: 69f9c33d71c871fc16ac445211281c6e7a340943
commit-date: 2022-12-12
host: x86_64-pc-windows-msvc
release: 1.66.0
LLVM version: 15.0.2
Backtrace

No additional info from setting the environment variable. I suspect it's because BACKTRACE doesn't deal with the borrow checker?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions