What is the difference between AsMut and &mut

why do i need to reborrow in the following example.

I need to reborrow when i use a function that takes generic type AsMut, i don't have reborrow when i use a function that takes a mutable reference?

pub fn refref<I, O, InType, OutType>(inputs: I, mut outputs: O)
where
    I: AsRef<[InType]>,
    O: AsMut<[OutType]>,
    InType: AsRef<[f32]>,
    OutType: AsMut<[f32]>,
{
    let i = inputs.as_ref()[0].as_ref()[0];
    outputs.as_mut()[0].as_mut()[0] = 1.0;
    let o = outputs.as_mut()[0].as_mut()[0];
    println!("{i}{o}");
}

pub fn andref<IBB, OBB>(inputs: &[IBB], outputs: &mut [OBB])
where
    IBB: AsRef<[f32]>,
    OBB: AsMut<[f32]>,
{
    let i = inputs[0].as_ref()[0];
    outputs[0].as_mut()[0] = 1.0;
    let o = outputs[0].as_mut()[0];
    println!("{i}{o}");
}

fn main() {
    //vectors of slices
    let v1: Vec<f32> = vec![0f32; 16];
    let v2: Vec<f32> = vec![0f32; 16];
    let mut v3: Vec<f32> = vec![0f32; 16];
    let mut v4: Vec<f32> = vec![0f32; 16];

    let ivs: Vec<&[f32]> = vec![v1.as_slice(), v2.as_slice()];
    let mut ovs: Vec<&mut [f32]> = vec![v3.as_mut_slice(), v4.as_mut_slice()];

    //slices of slices
    let iss: &[&[f32]] = ivs.as_slice();
    let oss: &mut [&mut [f32]] = ovs.as_mut_slice();

    refref(iss, &mut *oss);//why do i need to reborrow here?
    andref(iss, oss);
}

additionally i think i am a bit confused how reborring works exactly.

If a reference specifically is expected, and you pass in a &mut _, it will be implicitly reborrowed. refref doesn't specifically take a reference, it takes a generic parameter, and the implicit reborrowing doesn't kick in.

Here's an even simpler example:

fn main() {
    let mut s = String::new();
    let ms = &mut s;
    
    // This reborrows `*ms` and does not move it
    let _explicitly_a_reference: &mut _ = ms;
    
    // This moves `ms`
    let _not_explicitly_a_reference = ms;
    
    drop(ms);
}

Reborrows are surprisingly underdocumented, including when something is implicitly reborrowed and when it's not. I think it's closely related to when coercions kick in.

1 Like