Why can't I put up with the primitive from the enumeration?

I would like to get links (both immutable and mutable) to usize wrapped in Bar in a Foo enumeration:

 use Foo::*; #[derive(Debug, PartialEq, Clone)] pub enum Foo { Bar(usize) } impl Foo { /* this works */ fn get_bar_ref(&self) -> &usize { match *self { Bar(ref n) => &n } } /* this doesn't */ fn get_bar_ref_mut(&mut self) -> &mut usize { match *self { Bar(ref mut n) => &mut n } } } 

But I can’t get a mutable link because:

n not long enough

I was able to provide both options for similar functions that access other Foo content that Box ed - why does the replaceable borrowed (and why only it) fail with an unboxed primitive?

+8
enums rust borrow-checker
source share
2 answers

These examples show a sample problem:

 fn implicit_reborrow<T>(x: &mut T) -> &mut T { x } fn explicit_reborrow<T>(x: &mut T) -> &mut T { &mut *x } fn implicit_reborrow_bad<T>(x: &mut T) -> &mut T { &mut x } fn explicit_reborrow_bad<T>(x: &mut T) -> &mut T { &mut **&mut x } 

In explicit_ versions, it is shown that the compiler outputs via deref coercions .
In _bad versions _bad both errors are the same, and the other two are compiled.

This is either a mistake or a limitation on how implementers are currently implemented in the compiler. The invariance of &mut T over T may have something to do with it, because it leads to the fact that &mut &'a mut T is invariant compared to 'a and, therefore, more restrictive during output than the case with a common reference ( &&'a T ), although rigor is not needed in this situation.

+7
source share

You need to replace Bar(ref mut n) => &mut n with Bar(ref mut n) => n .

When you use ref mut n in Bar(ref mut n) , it creates a mutable data reference in Bar , so type n is &mut usize . Then you try to return &mut n type &mut &mut u32 .

This part is most likely incorrect.

Now deref coercion kicks and converts &mut n to &mut *n , creating a temporary value *n type usize that is not long enough.

+7
source share

All Articles