Under the new borrowing rules, if &const were removed, wouldn't it be safe
to temporarily deinitialize a mutably borrowed value as long as it can be
statically guaranteed that you reinitialize it before the next use?



On Saturday, 9 February 2013, Niko Matsakis wrote:

> Today I think the only way you could do this is like so:
>
>   fn extendH(v:&mut HasList) {
>        let w = util::replace(&mut v.l, ~MT);
>        v.l = ~Cons(3, w);
>   }
>
> Or, written using the swap operator:
>
>   fn extendH(v:&mut HasList) {
>        let mut w = ~MT;
>        v.l<->  w;
>        v.l = ~Cons(3, w);
>   }
>
> This unfortunately requires a temporary allocation of ~MT to "plug into"
> v.l in the interim before you have updated its value.  You could avoid this
> by using an Option type, which at least wouldn't require allocation.
>  However, I think we could also add a helper like `util::replace()` that
> updates the value "in-place", as you originally wanted.  I imagine
> something like this:
>
>     fn update<T>(v: &mut T, f: &fn(T) -> T) { unsafe { ... } }
>
> and then you would write:
>
>   fn extendH(v:&mut HasList) {
>         util::update(&mut v.l, |l| ~Cons(3, l));
>   }
>
>
>
>
> Niko
>
> John Clements wrote:
>
>> I'm trying to figure out a clean way to juggle ownership to rearrange the
>> parts of a mutable structure.  Specifically, in the example below, I want
>> to take a field containing an owned pointer and mutate it to point to a
>> different structure that contains the original value. After the move, the
>> pointer is again owned by the same structure, but the borrow checker is
>> unhappy with me.
>>
>> I've tried a bunch of variations using intermediate variables and
>> 'match'ing, but none of them have worked. Actually, it seems like I need an
>> atomic operation like the one described by Tucker Taft, where I move and
>> simultaneously set-to-null….
>>
>> Is there some way to make this happen?[*]
>>
>>
>> // a list that uses owned pointers
>> pub enum IntList {
>>      MT,
>>      Cons(int,~IntList)
>> }
>>
>> // a structure containing a list
>> pub struct HasList {
>>      a : ~str,
>>      l : ~IntList
>> }
>>
>> // add a '3' at the head of the contained list
>> fn extendH(v:&mut HasList) {
>>      v.l = ~Cons(3,v.l);
>> }
>>
>> #[test] fn t1() {
>>      let h = ~mut HasList {a:~"bogus",l:~MT};
>>      extendH(h);
>> }
>>
>> ==>
>>
>> rustc --test foo.rs
>> Running /usr/local/bin/rustc:
>> foo.rs:13:4: 13:5 error: use of partially moved value: `v`
>> foo.rs:13     v.l = ~Cons(3,v.l);
>>                ^
>> foo.rs:13:18: 13:21 note: field of `v` moved here because the field has
>> type ~IntList, which is moved by default (use `copy` to override)
>> foo.rs:13     v.l = ~Cons(3,v.l);
>>                              ^~~
>> foo.rs:13:4: 13:5 error: use of partially moved value: `v`
>> foo.rs:13     v.l = ~Cons(3,v.l);
>>                ^
>> foo.rs:13:18: 13:21 note: field of `v` moved here because the field has
>> type ~IntList, which is moved by default (use `copy` to override)
>> foo.rs:13     v.l = ~Cons(3,v.l);
>>                              ^~~
>> error: aborting due to 2 previous errors
>>
>>
>>
>> John
>>
>>
>> [*] Naturally, I could just use a vector rather than the cons-pair
>> representation; I'm not looking for that answer.
>>
>> ______________________________**_________________
>> Rust-dev mailing list
>> [email protected]
>> https://mail.mozilla.org/**listinfo/rust-dev<https://mail.mozilla.org/listinfo/rust-dev>
>>
> ______________________________**_________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/**listinfo/rust-dev<https://mail.mozilla.org/listinfo/rust-dev>
>
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to