Is this a shortcoming of the compiler?

Why does the compiler report an error after replacing mark 2 with a mark 1 sentence? Essentially, there is no significant difference between the two, so is this a shortcoming of the compiler?

#[derive(Debug)]
struct MyType {
    a: [usize; 10],
    b: [usize; 10],
}

impl MyType {
    pub fn get_a(&self) -> &[usize] {
        &self.a
    }
    pub fn init(&mut self) {
        // let a_ref = self.get_a();    /** mark 1 **/
        let a_ref = &self.a;           /** mark 2 **/

        let b_ref = &mut self.b;

        for (i, &a_val) in a_ref.iter().enumerate() {
            b_ref[i] = if a_val == 0 { 0 } else { 1 };
        }
    }
}

fn main() {
    let mut t = MyType {
        a: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
        b: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
    };

    t.init();
    println!("Hello, world!");
    println!("{:?}", t);
}

The unelided version of get_a:

pub fn get_a<'a>(&'a self) -> &'a [usize] {...}

This means the whole self would be borrowed for &'a [usize], unlike mark 2 where only field self.a would be borrowed.
I think this is correct behavior(it should be rejected). If this was allowed you can break outer code by changing get_a to return self.b instead of self.a.

4 Likes

You can basically consider the function signature to be a contract between caller and callee. Changes to the function body don't change the contract, so can't break downstream code.[1] Or from the other point of view, the caller must assume the function body does everything allowed by the contract.

The contract in this case is indeed "all of self is borrowed".[2]

The ability to borrow individual fields in function bodies is also called borrow splitting.


  1. there are some exceptions around opaque return types and auto-traits ↩︎

  2. there's an interest in more refined borrow signatures and/or functions that leak their borrowing details, but they're probably a ways off. See also "view types" ↩︎

2 Likes

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.