fn add_assign<'v>(lhs: Value<'v>, rhs: Value<'v>, heap: &'v Heap) -> anyhow::Result<Value<'v>> {
    // Addition of strings is super common, so have a special case
    if let Some(ls) = lhs.unpack_str() {
        if let Some(rs) = rhs.unpack_str() {
            if ls.is_empty() {
                return Ok(rhs);
            } else if rs.is_empty() {
                return Ok(lhs);
            } else {
                return Ok(heap.alloc_str_concat(ls, rs));
            }
        }
    }

    // The Starlark spec says list += mutates, while nothing else does.
    // When mutating, be careful if they alias, so we don't have `lhs`
    // mutably borrowed when we iterate over `rhs`, as they might alias.

    let lhs_aref = lhs.get_ref();
    let lhs_ty = lhs_aref.static_type_of();

    if List::is_list_type(lhs_ty) {
        // If the value is None, that must mean its a FrozenList, thus turn it into an immutable error
        let mut list = List::from_value_mut(lhs)?
            .ok_or_else(|| anyhow!(ValueError::CannotMutateImmutableValue))?;
        if lhs.ptr_eq(rhs) {
            list.content.extend_from_within(..);
        } else {
            rhs.with_iterator(heap, |it| list.content.extend(it))?;
        }
        Ok(lhs)
    } else if let Some(v) = rhs.get_ref().radd(lhs, heap) {
        v
    } else {
        lhs_aref.add(rhs, heap)
    }
}
/// Implement lhs += rhs, which is special in Starlark, because lists are mutated,
/// while all other types are not.
Implement lhs += rhs, which is special in Starlark, because lists are mutated,
while all other types are not.
Implement lhs + = rhs which is special in Starlark because lists are mutated while all other types are not .
fn add_assign<'v>(lhs: Value<'v>, rhs: Value<'v>, heap: &'v Heap) -> anyhow::Result<Value<'v>> {
    // Addition of strings is super common, so have a special case
    if let Some(ls) = lhs.unpack_str() {
        if let Some(rs) = rhs.unpack_str() {
            if ls.is_empty() {
                return Ok(rhs);
            } else if rs.is_empty() {
                return Ok(lhs);
            } else {
                return Ok(heap.alloc_str_concat(ls, rs));
            }
        }
    }
    // The Starlark spec says list += mutates, while nothing else does.
    // When mutating, be careful if they alias, so we don't have `lhs`
    // mutably borrowed when we iterate over `rhs`, as they might alias.
    let lhs_aref = lhs.get_ref();
    let lhs_ty = lhs_aref.static_type_of();
    if List::is_list_type(lhs_ty) {
        // If the value is None, that must mean its a FrozenList, thus turn it into an immutable error
        let mut list = List::from_value_mut(lhs)?
            .ok_or_else(|| anyhow!(ValueError::CannotMutateImmutableValue))?;
        if lhs.ptr_eq(rhs) {
            list.content.extend_from_within(..);
        } else {
            rhs.with_iterator(heap, |it| list.content.extend(it))?;
        }
        Ok(lhs)
    } else if let Some(v) = rhs.get_ref().radd(lhs, heap) {
        v
    } else {
        lhs_aref.add(rhs, heap)
    }
}
fn add_assign < ' v > ( lhs : Value < ' v > , rhs : Value < ' v > , heap : & ' v Heap ) -> anyhow :: Result < Value < ' v > > { // Addition of strings is super common, so have a special case if let Some ( ls ) = lhs . unpack_str ( ) { if let Some ( rs ) = rhs . unpack_str ( ) { if ls . is_empty ( ) { return Ok ( rhs ) ; } else if rs . is_empty ( ) { return Ok ( lhs ) ; } else { return Ok ( heap . alloc_str_concat ( ls , rs ) ) ; } } } // The Starlark spec says list += mutates, while nothing else does. // When mutating, be careful if they alias, so we don't have `lhs` // mutably borrowed when we iterate over `rhs`, as they might alias. let lhs_aref = lhs . get_ref ( ) ; let lhs_ty = lhs_aref . static_type_of ( ) ; if List :: is_list_type ( lhs_ty ) { // If the value is None, that must mean its a FrozenList, thus turn it into an immutable error let mut list = List :: from_value_mut ( lhs ) ? . ok_or_else ( | | anyhow ! ( ValueError CannotMutateImmutableValue ) ) ? ; if lhs . ptr_eq ( rhs ) { list . content . extend_from_within ( .. ) ; } else { rhs . with_iterator ( heap , | it | list . content . extend ( it ) ) ? ; } Ok ( lhs ) } else if let Some ( v ) = rhs . get_ref ( ) . radd ( lhs , heap ) { v } else { lhs_aref . add ( rhs , heap ) } }
Implement lhs += rhs, which is special in Starlark, because lists are mutated,
while all other types are not.
Implement lhs + = rhs which is special in Starlark because lists are mutated while all other types are not .
lhs
Value<'v>
rhs
Value<'v>
heap
&'v Heap
lhs
Value<'v>
rhs
Value<'v>
heap
&'v Heap