lifetime mismatch - Return a referenced mutable variable - reference

I have structs of different shapes:
struct Triangle { points: Vec<u8> }
struct Square { points: Vec<u8> }
struct Pentagon { points: Vec<u8> }
I have a trait CursorReadWrite:
use std::io::Cursor;
pub trait CursorReadWrite {
fn mwrite(&mut self, writer: &mut Cursor<Vec<u8>>) -> &mut Cursor<Vec<u8>>;
fn mread(&mut self, reader: &mut Cursor<Vec<u8>>);
}
I can implement it for Triangle, Square etc
impl CursorReadWrite for Triangle {
fn mwrite(&mut self, writer: &mut Cursor<Vec<u8>>) -> &mut Cursor<Vec<u8>> {
//do some work and write the data on Cursor<>
writer.write(somedata);
return writer;
}
fn mread(&mut self, reader: &mut Cursor<Vec<u8>>) {
//read data and do some work and save it in mutable self ( Triangle, Square etc)
self.points = somedata;
}
}
Call the function like this
let csd = Cursor::new(Vec::<u8>::new());
let mut t = Triangle::default();
let new_csd = t.mwrite(&mut csd);
t.mread(&mut new_csd);
It gives this error
error[E0623]: lifetime mismatch
|
25 | fn mwrite(&mut self,writer: &mut Cursor<Vec<u8>>) -> &mut Cursor<Vec<u8>>{
| -------------------- ----------------------------
| |
| this parameter and the return type are declared with different lifetimes...
...
28 | return writer;
| ^^^^^^^^^^^^ ...but data from `writer` is returned here

It's not easy to fix your code, because there are plenty of missing pieces, but you might want to re-define mwrite with explicit lifetimes:
pub trait CursorReadWrite<'a, 'b> {
fn mwrite(&'a mut self, writer: &'b mut Cursor<Vec<u8>>) -> &'b mut Cursor<Vec<u8>>;
fn mwread(&mut self, reader: &mut Cursor<Vec<u8>>);
}
impl<'a, 'b> CursorReadWrite<'a, 'b> for Triangle{
fn mwrite(&'a mut self, writer: &'b mut Cursor<Vec<u8>>) -> &'b mut Cursor<Vec<u8>>{
...
}
}
When you have more than 1 input lifetime the compiler can't tell which one you want to pick for the output. Citing lifetime elision rules:
Each parameter that is a reference gets its own lifetime parameter. In other words, a function with one parameter gets one lifetime
parameter: fn foo<'a>(x: &'a i32), a function with two arguments gets
two separate lifetime parameters: fn foo<'a, 'b>(x: &'a i32, y: &'b i32), and so on.
(...)
If there are multiple input lifetime parameters, but one of them is &self or &mut self because this is a method, then the lifetime of self
is assigned to all output lifetime parameters. (...)

Related

Can a trait's impl specify a lifetime that comes from a method's input argument?

For a type
pub struct Child<'a> {
buf: &'a mut [u8],
}
I can define a trait and implement the trait for the type but with a lifetime that is bound to a calling function's context (not to a local loop context):
pub trait MakeMut<'a> {
fn make_mut(buf: &'a mut [u8]) -> Self;
}
impl<'a> MakeMut<'a> for Child<'a> {
fn make_mut(buf: &'a mut [u8]) -> Self {
Self { buf }
}
}
And first to show a somewhat working example because x is only borrowed within the context of the loop because Child::make_mut is hardcoded in the map1 function:
pub fn map1<F>(mut func: F)
where
F: FnMut(&mut Child),
{
let mut vec = vec![0; 16];
let x = &mut vec;
for i in 0..2 {
let offset = i * 8;
let s = &mut x[offset..];
let mut w = Child::make_mut(s);
func(&mut w);
}
}
But in trying to make map2, a generic version of map1 where the T is bound to the MakeMut trait but with lifetime of the entire function body, this won't compile, for good reasons (the T lifetimes that would be created by T: MakeMut<'a> have the lifetime of map2, not the inner loop):
pub fn map2<'a, F, T>(mut func: F) // lifetime `'a` defined here
where
T: MakeMut<'a>,
F: FnMut(&mut T),
{
let mut vec = vec![0; 16];
let x = &mut vec;
for i in 0..2 {
let offset = i * 8;
let s = &mut x[offset..];
let mut w = T::make_mut(s); // error: argument requires that `*x` is borrowed for `'a`
func(&mut w);
}
}
I want to do something almost like this but of course it doesn't compile either:
pub trait MakeMut {
fn make_mut<'a>(buf: &'a mut [u8]) -> Self;
}
impl<'a> MakeMut for Child<'a> {
fn make_mut(buf: &'a mut [u8]) -> Self { // lifetime mismatch
Self{ buf }
}
}
with the compiler errors:
error[E0308]: method not compatible with trait
--> src/main.rs:45:5
|
45 | fn make_mut(buf: &'a mut [u8]) -> Self {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected fn pointer `fn(&'a mut [u8]) -> Child<'_>`
found fn pointer `fn(&'a mut [u8]) -> Child<'_>`
note: the lifetime `'a` as defined here...
--> src/main.rs:45:5
|
45 | fn make_mut(buf: &'a mut [u8]) -> Self {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...does not necessarily outlive the lifetime `'a` as defined here
--> src/main.rs:44:6
|
44 | impl<'a> MakeMut for Child<'a> {
| ^^
Is there a syntax that allows a trait for a Child<'a> where the 'a is defined by the input argument to the method make_mut? So a generic function could be defined for a trait that returns an instance but where the instance lifetime is not the entire function, but just a shorter lifetime defined by an inner block?
I understand the lifetime is part of the type being returned, but it almost seems like a higher-ranked trait bound (HRTB) would suite this problem except I haven't found a way to specify the lifetime that suites the trait and the method signatures.
Here is a playground link https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=fb28d6da9d89fde645edeb1ca0ae5b21
Your first attempt is close to what you want. For reference:
pub trait MakeMut<'a> {
fn make_mut(buf: &'a mut [u8]) -> Self;
}
impl<'a> MakeMut<'a> for Child<'a> {
fn make_mut(buf: &'a mut [u8]) -> Self {
Self { buf }
}
}
The first problem is the bound on T in map2:
pub fn map2<'a, F, T>(mut func: F)
where
T: MakeMut<'a>,
F: FnMut(&mut T),
This requires the compiler to deduce a single 'a that applies for the whole function. Since lifetime parameters come from outside of the function, the lifetime 'a is necessarily longer than the function invocation, which means anything with lifetime 'a has to outlive the function. Working backwards from the T::make_mut() call, the compiler eventually deduces that x is &'a mut Vec<_> which means vec has to outlive the function invocation, but there's no possible way it can since it's a local.
This can be fixed by using a higher-rank trait bound indicating that T has to implement MakeMut<'a> for any possible lifetime 'a, which is expressed like this:
pub fn map2<F, T>(mut func: F)
where
T: for<'a> MakeMut<'a>,
F: FnMut(&mut T),
With this change, the code compiles.
What you'll then find is that you can't ever actually call map2 with T=Child<'_> because you'll run into the same problem in a different place. The caller must specify a specific lifetime for 'a in Child<'a>, but this disagrees with the HRTB -- you have impl<'a> MakeMut<'a> for Child<'a> but the HRTB wants impl<'a, 'b> MakeMut<'b> for Child<'a>, and that brings back the lifetime problem in that implementation's make_mut.
One way around this is to decouple the implementation of MakeMut from Child, providing a "factory type" that uses associated types. This way, the caller doesn't have to supply any pesky lifetime argument that could cause trouble later.
pub trait MakeMut<'a> {
type Item;
fn make_mut(buf: &'a mut [u8]) -> Self::Item;
}
struct ChildFactory;
impl<'a> MakeMut<'a> for ChildFactory {
type Item = Child<'a>;
fn make_mut(buf: &'a mut [u8]) -> Child<'a> {
Child { buf }
}
}
Then we modify map2 to be aware of the associated type:
pub fn map2<F, T>(mut func: F)
where
T: for<'a> MakeMut<'a>,
F: for<'a, 'b> FnMut(&'b mut <T as MakeMut<'a>>::Item),
whew
Now, finally, we can use map2:
map2::<_, ChildFactory>(|v| {});
(Playground)

Generic parameter with reference used as function pointer argument

I am having trouble figuring out what lifetime parameter will work for this, so my current workarounds include transmutes or raw pointers. I have a structure holding a function pointer with a generic as a parameter:
struct CB<Data> {
cb: fn(Data) -> usize
}
I would like to store an instance of that, parameterized by some type containing a reference, in some other structure that implements a trait with one method, and use that trait method to call the function pointer in CB.
struct Holder<'a> {
c: CB<Option<&'a usize>>
}
trait Exec {
fn exec(&self, v: &usize) -> usize;
}
impl<'a> Holder<'a> {
fn exec_aux(&self, v: &'a usize) -> usize {
(self.c.cb)(Some(v))
}
}
impl<'a> Exec for Holder<'a> {
fn exec(&self, v: &usize) -> usize
{
self.exec_aux(v)
}
}
This gives me a lifetime error for the 'Exec' impl of Holder:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
Simply calling exec_aux works fine as long as I don't define that Exec impl:
fn main() {
let h = Holder { c: CB{cb:cbf}};
let v = 12;
println!("{}", h.exec_aux(&v));
}
Also, making CB not generic also makes this work:
struct CB {
cb: fn(Option<&usize>) -> usize
}
The parameter in my actual code is not a usize but something big that I would rather not copy.
The lifetimes in your Exec trait are implicitly this:
trait Exec {
fn exec<'s, 'a>(&'s self, v: &'a usize) -> usize;
}
In other words, types that implement Exec need to accept any lifetimes 's and 'a. However, your Holder::exec_aux method expects a specific lifetime 'a that's tied to the lifetime parameter of the Holder type.
To make this work, you need to add 'a as a lifetime parameter to the Exec trait instead, so that you can implement the trait specifically for that lifetime:
trait Exec<'a> {
// ^^^^ vv
fn exec(&self, v: &'a usize) -> usize;
}
impl<'a> Exec<'a> for Holder<'a> {
// ^^^^ vv
fn exec(&self, v: &'a usize) -> usize
{
self.exec_aux(v)
}
}
The problem here is that the Exec trait is too generic to be used in this way by Holder. First, consider the definition:
trait Exec {
fn exec(&self, v: &usize) -> usize;
}
This definition will cause the compiler to automatically assign two anonymous lifetimes for &self and &v in exec. It's basically the same as
fn exec<'a, 'b>(&'a self, v: &'b usize) -> usize;
Note that there is no restriction on who needs to outlive whom, the references just need to be alive for the duration of the method call.
Now consider the definition
impl<'a> Holder<'a> {
fn exec_aux(&self, v: &'a usize) -> usize {
// ... doesn't matter
}
}
Since we know that &self is a &Holder<'a> (this is what the impl refers to), we need to have at least a &'a Holder<'a> here, because &'_ self can't have a lifetime shorter than 'a in Holder<'a>. So this is saying that the two parameters have the same lifetime: &'a self, &'a usize.
Where it all goes wrong is when you try to combine the two. The trait forces you into the following signature, which (again) has two distinct implicit lifetimes. But the actual Holder which you then try to call a method on forces you to have the same lifetimes for &self and &v.
fn exec(&self, v: &usize) -> usize {
// Holder<'a> needs `v` to be `'a` when calling exec_aux
// But the trait doesn't say so.
self.exec_aux(v)
}
One solution is to redefine the trait as
trait Exec<'a> {
fn exec(&'a self, v: &'a usize) -> usize;
}
and then implement it as
impl<'a> Exec<'a> for Holder<'a> {
fn exec(&'a self, v: &'a usize) -> usize {
self.exec_aux(v)
}
}

`cannot infer an appropriate lifetime for autoref due to conflicting requirements` but can't change anything due to trait definition constraints

I was implementing linked lists by following along too many linked lists. When trying to implement iter_mut(), I did it myself and made the following code:
type Link<T> = Option<Box<Node<T>>>;
pub struct List<T> {
head: Link<T>,
}
struct Node<T> {
elem: T,
next: Link<T>,
}
impl<T> List<T> {
pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut::<T>(&mut self.head)
}
}
pub struct IterMut<'a, T>(&'a mut Link<T>);
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next<'b>(&'b mut self) -> Option<&'a mut T> {
self.0.as_mut().map(|node| {
self.0 = &mut (**node).next;
&mut (**node).elem
})
}
}
I am to avoiding coersions and elisions because being explicit lets me understand more.
Error:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/third.rs:24:16
|
24 | self.0.as_mut().map(|node| {
| ^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'b` as defined on the method body at 23:13...
--> src/third.rs:23:13
|
23 | fn next<'b>(&'b mut self) -> Option<&'a mut T> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/third.rs:24:9
|
24 | self.0.as_mut().map(|node| {
| ^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 20:6...
--> src/third.rs:20:6
|
20 | impl<'a, T> Iterator for IterMut<'a, T> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/third.rs:25:22
|
25 | self.0 = &mut (**node).next;
| ^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0495`.
I have looked at Cannot infer an appropriate lifetime for autoref due to conflicting requirements.
I understand a bit but not much. The problem that I am facing here is that if I try to change anything, an error pops saying that can't match the trait definition.
My thought was that basically I need to state somehow that lifetime 'b outlives 'a i.e <'b : 'a> but I can't figure out how to do it. Also, I have similar functions to implement iter() which works fine. It confuses me why iter_mut() produces such errors.
Iter
type Link<T> = Option<Box<Node<T>>>;
pub struct Iter<'a, T>(&'a Link<T>);
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.0.as_ref().map(|node| {
self.0 = &((**node).next);
&((**node).elem)
})
}
}
impl<T> List<T> {
pub fn iter(&self) -> Iter<T> {
Iter::<T>(&self.head)
}
}
☝️This works.
The key thing is that you need to be able to somehow extract an Option<&'a mut T> from a &'b mut IterMut<'a, T>.
To understand why IterMut<'a, T> := &'a mut Link<T> can't work, you need to understand what exactly you can do with a mutable reference. The answer, of course, is almost everything. You can copy data out of it, change its value, and lots of other things. The one thing you can't do is invalidate it. If you want to move the data under the mutable reference out, it has to be replaced with something of the same type (including lifetimes).
Inside the body of next, self is (essentially) &'b mut &'a mut Link<T>. Unless we know something about T (and we can't in this context), there's simply no way to produce something of type &'a mut Link<T> from this. For example, if this were possible in general, we'd be able to do
fn bad<'a, 'b, T>(_x: &'b mut &'a mut T) -> &'a mut T {
todo!()
}
fn do_stuff<'a>(x: &'a mut i32, y: &'a mut i32) {
// lots of stuff that only works if x and y don't alias
*x = 13;
*y = 42;
}
fn main() {
let mut x: &mut i32 = &mut 0;
let y: &mut i32 = {
let z: &mut &mut i32 = &mut x;
bad(z)
};
// `x` and `y` are aliasing mutable references
// and we can use both at once!
do_stuff(x, y);
}
(playground link)
The point is that if we were able to borrow something for a short (generic) lifetime 'b and return something that allowed modification during the longer lifetime 'a, we'd be able to use multiple short lifetimes (shorter than 'a and non-overlapping) to get multiple mutable references with the same lifetime 'a.
This also explains why the immutable version works. With immutable references, it's trivial to go from &'b &'a T to &'a T: just deference and copy the immutable reference. By contrast, mutable references don't implement Copy.
So if we can't produce a &'a mut Link<T> from a &'b mut &'a mut Link<T>, we certainly can't get an Option<&'a mut T out of it either (other than None). (Note that we can produce a &'b mut Link<T> and hence an Option<'b mut T>. That's what your code does right now.)
So what does work? Remember our goal is to be able to produce an Option<&'a mut T> from a &'b mut IterMut<'a, T>.
If we were able to produce a IterMut<'a, T> unconditionally, we'd be able to (temporarily) replace self with it and hence be able to directly access the IterMut<'a, T> associated to our list.
// This actually type-checks!
fn next<'b>(&'b mut self) -> Option<&'a mut T> {
let mut temp: IterMut<'a, T> = todo!(); // obviously this won't work
std::mem::swap(&mut self.0, &mut temp.0);
temp.0.as_mut().map(|node| {
self.0 = &mut node.next;
&mut node.elem
})
}
(playground link)
The easiest way to set things up so that this all works is by transposing IterMut<'a, T> a bit. Rather than having the mutable reference outside the option, make it inside! Now you'll always be able to produce an IterMut<'a, T> with None!
struct IterMut<'a, T>(Option<&mut Box<Node<T>>>);
Translating next, we get
fn next<'b>(&'b mut self) -> Option<&'a mut T> {
let mut temp: IterMut<'a, T> = IterMut(None);
std::mem::swap(&mut self.0, &mut temp.0);
temp.0.map(|node| {
self.0 = node.next.as_mut();
&mut node.elem
})
}
More idiomatically, we can use Option::take rather than std::mem::swap (This is mentioned earlier in Too Many Linked Lists).
fn next<'b>(&'b mut self) -> Option<&'a mut T> {
self.0.take().map(|node| {
self.0 = node.next.as_mut();
&mut node.elem
})
}
(playground link)
This actually ends up being slightly different than the implementation in Too Many Linked Lists. That implementation removes the double indirection of &mut Box<Node<T>> and replaces it with simply &mut Node<T>. However, I'm not sure how much you gain since that implementation still has a double deref in List::iter_mut and Iterator::next.
Rust is trying to say that you have a dangling reference.
self.0.as_mut() // value borrowed
self.0 = <> // underlying value changed here.
The problem is the following definition:
pub struct IterMut<'a, T>(&'a mut Link<T>)
This can't encapsulate that you will have a "empty" node meaning reached the end of the node.
Use the structure as mentioned in the book like:
pub struct IterMut<'a, T>(Option<&'a mut Node<T>>);
This ensures that you can leave None in its place when you run end of list and use take to modify the IterMut content behind the scenes.

Cannot borrow variable as mutable more than once at a time after calling a &'a mut self method

I have a problem with lifetimes/borrowing with my Graph object.
fn main() {
let mut g = Graph {
nodePointer: &mut 0,
edgePointer: &mut 0,
nodes: &mut Vec::new(),
edges: &mut Vec::new(),
};
let node1 = g.add_node((1, 1));
let node2 = g.get_node(0);
}
pub struct Graph<'a> {
pub nodePointer: &'a mut usize,
pub edgePointer: &'a mut usize,
pub nodes: &'a mut Vec<Node>,
pub edges: &'a mut Vec<Edge>,
}
impl<'a> Graph<'a> {
pub fn add_node(&'a mut self, data: (u64, u64)) -> usize {
let id: usize = *self.nodePointer;
self.nodes.push(Node {
id: id,
datum: data,
});
*self.nodePointer += 1;
return id;
}
pub fn get_node(&'a mut self, id: usize) -> &'a Node {
return &self.nodes[id];
}
pub fn add_edge(&'a mut self, source: u64, target: u64, weight: u16) -> usize {
let id: usize = *self.nodePointer;
self.edges.push(Edge {
id: id,
source,
target,
weight,
});
*self.edgePointer = *self.edgePointer + 1;
return id;
}
}
pub struct Node {
pub id: usize,
pub datum: (u64, u64),
}
pub struct Edge {
pub id: usize,
pub source: u64,
pub target: u64,
pub weight: u16,
}
error[E0499]: cannot borrow `g` as mutable more than once at a time
--> src/main.rs:9:17
|
8 | let node1 = g.add_node((1, 1));
| - first mutable borrow occurs here
9 | let node2 = g.get_node(0);
| ^ second mutable borrow occurs here
10 | }
| - first borrow ends here
Your problem arises from a misuse of lifetimes, specifically in your signature of add_node:
pub fn add_node(&'a mut self, data: (u64, u64)) -> usize
In this signature, you are stating that add_node takes an &'a mut self on a Graph<'a>; in other words, you are telling Rust that this method needs to take a mutable borrow on the graph that can't be dropped before the end of the Graph's lifetime, 'a. But since it's the graph itself holding a reference to the graph, the only time that reference will be dropped is when the graph itself is dropped.
Since add_node doesn't require you to return a reference to any object within the struct, holding onto that borrow is irrelevant. If you alter your add_node method to remove the explicit lifetime:
pub fn add_node(&mut self, data: (u64, u64)) -> usize
then your example no longer raises an error, because add_node is now only borrowing self until it's finished with the function. (Under the hood, this effectively creates a second lifetime 'b and makes the signature into &'b mut self)
See the playground for proof.
Consider this :
struct Foo<'a> {
x: &'a i32,
}
As the book states:
So why do we need a lifetime here? We need to ensure that any reference to a Foo cannot outlive the reference to an i32 it contains.
If you write something like:
impl<'a> Graph<'a> {
pub fn add_node(&'a mut self, data: (u64, u64)) -> usize {
...
the lifetime declaration &'a mut self is not for the purpose of relating the lifetime of Graph instance with the contained references,
but for declaring that for mutable self references hold the same lifetime 'a declared for Graph field references:
fn main() {
let mut g = Graph { // <------------
nodePointer: &mut 0, // |
edgePointer: &mut 0, // lifetime |
nodes: &mut Vec::new(), // of Graph | 'a
edges: &mut Vec::new(), // references |
}; // |
let node1 = Graph::add_node(&mut g, (1, 1)); // |
let node2 = Graph::get_node(&mut g, 0); // |
} //<-------------
Where g.get_node(0) has been rewritten as Graph::get_node(&mut g, 0) just for explicitly exposing the &mut reference
Looking at the lifetime of 'a it is clear that the reference &mut g is borrowed mutably more than once, and this causes the error.

How to have a struct field with the same mutability as the parent struct?

I'm trying to wrap a slice in a struct so that I will be able to instantiate the struct mutably or immutably. Here's a minimal example:
use std::ops::{ Index, IndexMut };
struct Test<'a, T: 'a> {
inner: &'a[T]
}
impl<'a, T: 'a> Test<'a, T> {
fn new (inner: &'a[T]) -> Self { Test { inner: inner } }
}
impl<'a, T> Index<usize> for Test<'a, T> {
type Output = T;
fn index (&self, i: usize) -> &T { &self.inner[i] }
}
impl<'a, T> IndexMut<usize> for Test<'a, T> {
fn index_mut (&mut self, i: usize) -> &mut T { &mut self.inner[i] }
}
fn main() {
let store = [0; 3];
let test = Test::new (&store);
println!("{}", test[1]);
let mut mut_store = [0; 3];
let mut mut_test = Test::new (&mut mut_store);
mut_test[1] = 42;
println!("{}", mut_test[1]);
}
This doesn't compile: "cannot borrow immutable indexed content self.inner[..] as mutable".
I could get it to compile by changing the definition of inner to be of type &'a mut[T], but then inner is mutable even when I don't need it to be (in the above example, I must then declare store as mutable too even though test is immutable).
Is there a way to make it so that the mutability of inner follows the mutability of the Test instance?
As well said in the question, this code compiles:
struct Test<'a, A: 'a> {
inner: &'a mut A,
}
fn main() {
let t = Test { inner: &mut 5i32 };
*t.inner = 9;
}
It is indeed possible to mutate a borrowed element, even when the borrowing content is immutable. This is a case where you must choose your guarantees, while keeping in mind that the mutability of a binding is always independent of the borrowed content's mutability.
Right now, I can think of two possible solutions: you can encapsulate the borrowed content over methods that depend on self's mutability (Playground, will no longer compile):
impl<'a, A: 'a> Test<'a, A> {
fn inner(&self) -> &A {
self.inner
}
fn inner_mut(&mut self) -> &mut A {
self.inner
}
}
Although you still need to keep a borrow to mutable content, it can no longer be mutated from an immutable binding of Test. If you also need it to point to immutable content, you should consider having two different structs (Playground):
struct Test<'a, A: 'a> {
inner: &'a A,
}
impl<'a, A: 'a> Test<'a, A> {
fn inner(&self) -> &A {
self.inner
}
}
struct TestMut<'a, A: 'a> {
inner: &'a mut A,
}
impl<'a, A: 'a> TestMut<'a, A> {
fn inner(&self) -> &A {
self.inner
}
fn inner_mut(&mut self) -> &mut A {
self.inner
}
}
There is a third option: to keep both kinds of borrows exclusively with an enum. At this point however, using the borrowed content as mutable requires run-time checks.

Resources