Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Inmutable and Mutable borrows in a call to "const" method for a "const" parameter

I can’t understand why Rust complains ("can’t borrow as immutable because also borrowed as mutable") in this code (even considering that .len() is a "constant/harmless" function):

fn main() {
    
    let mut xs1: [i32; 5] = [ 10, 20, 30, 40, 50];

    let (slice1, slice2) = xs1.split_at_mut( (xs1.len()/2) ); // <----- ERROR

    println!( "{:?}", slice1 );
    println!( "{:?}", slice2 );

    

} // ()

While the split version is fine:

let aux = xs1.len()/2;
let (slice1, slice2) = xs1.split_at_mut( aux );

What’s the rationale here?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Maybe I’m wrong but I always regarded both expressions as "mathematically equivalent" so to say. Not only len() should be a const method but also the input param for split_at_mut() should be const (in C++ parlance).

Still holding this question eight years later?

>Solution :

Maybe I’m wrong but I always regarded both expressions as "mathematically equivalent" so to say.

They are, but this here is an issue with the borrow checker, it is not perfect, and it has limitations.

In fact pretty much all static type systems without holes have will reject valid programs: the choice is to either reject valid programs or accept invalid ones.

And in this case as Sven Marnach notes it’s an artefact of the strict expression evaluation order: if you desugar the call to:

<[_]>::split_at_mut(&mut xs1, xs1.len()/2);

you get the same error.

In essence, Rust interprets

xs1.split_at_mut(xs1.len() / 2)

as

{
    let p1 = &mut xs1;
    {
        let p2 = xs1.len();
        {
            <[_]>::split_at_mut(p1, p2);
        }
    }
}

Not only len() should be a const method

… which it is?

but also the input param for split_at_mut() should be const (in C++ parlance).

That idea has no relevance to Rust, split_at_mut takes ownership of its (non-self) parameter.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading