I would like to hide the actual implementation that is returned from the create function by returning an impl trait as in create_trait(). How could this be done?
trait Names<'a> {
fn names(&'a self) -> &Vec<&'a str>;
}
struct NamesImpl<'b> {
names: Vec<&'b str>,
}
impl<'c> Names<'c> for NamesImpl<'c> {
fn names(&'c self) -> &Vec<&'c str> {
&self.names
}
}
fn create_impl<'i>() -> NamesImpl<'i> {
NamesImpl {
names: vec!["Hello", "world"],
}
}
#[allow(dead_code)]
fn create_trait<'t>() -> impl Names<'t> {
NamesImpl {
names: vec!["Hello", "world"],
}
}
fn main() {
let names_impl = create_impl();
println!("Names: {:?}", names_impl.names());
//This doesn't compile, see error below
let names_trait = create_trait();
println!("Names: {:?}", names_trait.names());
}
I can't wrap my head around the following compile error. Why does it work with create_impl() but not with create_trait()?
error[E0597]: `names_trait` does not live long enough
--> src/main.rs:34:29
|
34 | println!("Names: {:?}", names_trait.names());
| ^^^^^^^^^^^ borrowed value does not live long enough
35 | }
| -
| |
| `names_trait` dropped here while still borrowed
| borrow might be used here, when `names_trait` is dropped and runs the destructor for type `impl Names<'_>`
A general rule of thumb when it comes to using lifetimes in Rust is that if you don't know what you're doing, let the compiler infer the correct lifetimes for you. Once you get more experience, you'll learn when you actually need to use explicit lifetime annotations, but your example is not one of those situations. I was able make it compile by removing all the unnecessary lifetime annotations:
trait Names {
fn names(&self) -> &Vec<&str>;
}
struct NamesImpl<'a> {
names: Vec<&'a str>,
}
impl Names for NamesImpl<'_> {
fn names(&self) -> &Vec<&str> {
&self.names
}
}
fn create_impl() -> NamesImpl<'static> {
NamesImpl { names: vec!["Hello", "world"] }
}
fn create_trait() -> impl Names {
NamesImpl { names: vec!["Hello", "world"] }
}
fn main() {
let names_impl = create_impl();
println!("Names: {:?}", names_impl.names());
// compiles
let names_trait = create_trait();
println!("Names: {:?}", names_trait.names());
}
playground
To determine which lifetime annotations were unnecessary, I started by removing all of them and then only added lifetime annotations back to the areas where the compiler specifically asked me to.
This section in Common Rust Lifetime Misconceptions (Thank you pretzelhammer!) was an eye opener to me. It made mee see that in this construction
trait Names<'a> {
fn names(&'a self) -> &Vec<&'a str>;
}
calling names() will borrow the struct for the rest of its lifetime.
Correcting this in the original code with explicit lifetime annotations is possible, but the result is far from beautiful. I just tried this in an attempt to better understand the 'why'.
trait Names<'a : 'f, 'f> {
fn names(&self) -> &Vec<&'f str>;
}
struct NamesImpl<'b> {
names: Vec<&'b str>,
}
impl <'c : 'f, 'f> Names<'c, 'f> for NamesImpl<'c> {
fn names(&self) -> &Vec<&'f str> {
&self.names
}
}
fn create_impl<'i : 'f, 'f>() -> NamesImpl<'i> {
NamesImpl{names: vec!["Hello", "world"]}
}
#[allow(dead_code)]
fn create_trait<'t : 'f, 'f>() -> impl Names<'t, 'f> {
NamesImpl{names: vec!["Hello", "world"]}
}
fn main() {
let names_impl = create_impl();
println!("Names: {:?}", names_impl.names());
//This compiles
let names_trait = create_trait();
println!("Names: {:?}", names_trait.names());
}
Conclusion: Follow the advice given by Shepmaster
Related
I am designing code that should be generic over a trait Atom, that contains many associated types that logically belong together. In the simplified example below, which concerns representing a mathematical expression, there is one variant that gives a 'view' of a Pow and an owned version of a Pow. In actuality, there will be many more variants, such as Var and OwnedVar, Function and OwnedFunction, etc.
Since some traits deal with borrowed data, I added lifetimes and this makes the code below not compile:
pub trait Atom {
// imagine more variants here
type P<'a>: Pow<'a, R = Self>;
type OP: OwnedPow<R = Self>;
}
pub trait Pow<'a> {
type R: Atom;
fn get_base(&self) -> AtomView<Self::R>;
}
pub trait OwnedPow {
type R: Atom;
fn to_view<'a>(&'a self) -> AtomView<Self::R>;
}
pub enum AtomView<'a, R: Atom> {
Pow(R::P<'a>),
}
impl<'a, R: Atom> AtomView<'a, R> {
#[allow(unconditional_recursion, irrefutable_let_patterns)]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
if let AtomView::Pow(p2) = other {
let b = p2.get_base();
Some(self.partial_cmp(&b).unwrap())
} else {
None
}
}
}
// concrete implementations
struct Rep;
impl Atom for Rep {
type P<'a> = PowD<'a>;
type OP = OwnedPowD;
}
struct PowD<'a> {
data: &'a [u8],
}
impl<'a> Pow<'a> for PowD<'a> {
type R = Rep;
fn get_base(&self) -> AtomView<Self::R> {
AtomView::Pow(PowD {
data: &self.data[1..],
})
}
}
struct OwnedPowD {
data: Vec<u8>,
}
impl OwnedPow for OwnedPowD {
type R = Rep;
fn to_view<'a>(&'a self) -> AtomView<Rep> {
AtomView::Pow(PowD { data: &self.data })
}
}
fn test<A: OwnedPow>(a: A) {
let _vv = a.to_view();
}
fn main() {
let v = OwnedPowD {
data: vec![1, 2, 3],
};
test(v);
}
This code does not compile:
error[E0621]: explicit lifetime required in the type of `other`
--> src/main.rs:25:21
|
23 | fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
| ----- help: add explicit lifetime `'a` to the type of `other`: `&'a AtomView<'a, R>`
24 | if let AtomView::Pow(p2) = other {
25 | let b = p2.get_base();
| ^^^^^^^^^^^^^ lifetime `'a` required
Of course, giving other the lifetime a is a problem, since other is a locally created variable and thus following the help will not fix the problem. I fail to see why &b seems to have the lifetime &'a b.
The code can be tested on the playground.
I tried fixing this code by dropping many lifetimes in the associated types and traits, but then it seems I need to give Rep a lifetime, and then this Rep<'a> will make its way into OwnedPowD that should have no lifetime (since the data is owned). This attempt can be tried here.
Does anyone know how to assign proper lifetimes?
AtomView has a lifetime argument, which should connect all of the borrowing dependencies together. But you are never specifying it!
pub enum AtomView<'a, R: Atom> {
Pow(R::P<'a>),
}
I was able to make your code compile by changing the trait methods to constrain this lifetime in the "obvious" way in each case:
pub trait Pow<'a> {
type R: Atom;
fn get_base(&self) -> AtomView<'a, Self::R>;
}
pub trait OwnedPow {
type R: Atom;
fn to_view(&self) -> AtomView<'_, Self::R>;
}
And updating the implementations to match:
impl<'a> Pow<'a> for PowD<'a> {
type R = Rep;
fn get_base(&self) -> AtomView<'a, Self::R> {
// just for testing
AtomView::Pow(PowD {
data: &self.data[1..],
})
}
}
impl OwnedPow for OwnedPowD {
type R = Rep;
fn to_view(&self) -> AtomView<'_, Rep> {
AtomView::Pow(PowD { data: &self.data })
}
}
I have this trait and implementation:
#[async_trait]
pub trait AsyncKeyProvider {
async fn get_key_async(&mut self, key_id: &str) -> Result<Option<Jwk>, ()>;
fn as_any(&self) -> &dyn Any;
}
#[async_trait]
impl AsyncKeyProvider for GoogleKeyProvider {
async fn get_key_async(&mut self, key_id: &str) -> Result<Option<Jwk>, ()> {
{...}
}
fn as_any(&self) -> &dyn Any {
self
}
}
In order to pass it into my handler in actix-web, I'm passing through a GoogleKeyProvider like this:
let key_provider = web::Data::from(Arc::new(GoogleKeyProvider::default()));
let server = HttpServer::new(move || {
App::new()
.app_data(key_provider.clone())
.route("/validate", web::post().to(validate))
})
With the handler doing this:
pub async fn validate(jwt_body: web::Json<JwtBody>, provider: web::Data<Box<dyn AsyncKeyProvider>>) -> impl Responder {
let provider_object: &GoogleKeyProvider = provider.as_any().downcast_ref::<GoogleKeyProvider>().expect("Wasn't a GoogleKeyProvider");
match validate_jwt(&jwt_body.jwt, provider_object).await {
{...}
}
}
validate_jwt then tries to call a method on the provider struct like this:
async fn validate_jwt(jwt: &String, provider: &GoogleKeyProvider) -> Result<bool, Box<dyn std::error::Error>> {
let key_to_use = provider.get_key_async(<thing>).await.unwrap();
}
Which presents me with this error:
error[E0596]: cannot borrow `*provider` as mutable, as it is behind a `&` reference
--> src\routes\validate.rs:48:22
|
48 | let key_to_use = provider.get_key_async(<thing>).await.unwrap();
| ^^^^^^^^ `provider` is a `&` reference, so the data it refers to cannot be borrowed as mutable
As far as I can understand, this is happening because the result of my downcasting is a reference (due to downcast_ref), but I think I'd be wanting the plain GoogleKeyProvider type instead - I'm not sure on that though. I believe the provider needs to be mutable as the values inside it (see below) can change during the lifetime of the provider (it's intended to provide a temporary cache for some keys, and automatically update them if they're out of date)
#[derive(Clone)]
pub struct GoogleKeyProvider {
cached: Option<JwkSet>,
expiration_time: Instant,
}
I'm not sure how to get this working with downcasting, though. Is anyone able to help me see where I've gone wrong?
You have to choice if get_key_async update somme thing at the struct.
The simple code below show you the error
trait Atrait {
fn afn(&mut self) -> i32;
}
struct Astruct {}
impl Atrait for Astruct {
fn afn(&mut self) -> i32 {
2
}
}
fn main()
{
// test should be mutable
let test = Astruct{};
let value = test.afn();
println!("Value {}", value);
}
This work because afn(self) is not declared mutable afn(&mut self)
trait Atrait {
fn afn(&self) -> i32;
}
struct Astruct {}
impl Atrait for Astruct {
fn afn(&self) -> i32 {
2
}
}
fn main()
{
let test = Astruct{};
let value = test.afn();
println!("Value {}", value);
}
I'm trying to understand how to work with interior mutability. This question is strongly related to my previous question.
I have a generic struct Port<T> that owns a Vec<T>. We can "chain" port B to port A so, when reading the content of port A, we are able to read the content of port B. However, this chaining is hidden to port A's reader. That is why I implemented the iter(&self) method:
use std::rc::Rc;
pub struct Port<T> {
values: Vec<T>,
ports: Vec<Rc<Port<T>>>,
}
impl <T> Port<T> {
pub fn new() -> Self {
Self { values: vec![], ports: vec![] }
}
pub fn add_value(&mut self, value: T) {
self.values.push(value);
}
pub fn is_empty(&self) -> bool {
self.values.is_empty() && self.ports.is_empty()
}
pub fn chain_port(&mut self, port: Rc<Port<T>>) {
if !port.is_empty() {
self.ports.push(port)
}
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.values.iter().chain(
self.ports.iter()
.flat_map(|p| Box::new(p.iter()) as Box<dyn Iterator<Item = &T>>)
)
}
pub fn clear(&mut self) {
self.values.clear();
self.ports.clear();
}
}
The application has the following pseudo-code behavior:
create ports
loop:
fill ports with values
chain ports
iterate over ports' values
clear ports
The main function should look like this:
fn main() {
let mut port_a = Rc::new(Port::new());
let mut port_b = Rc::new(Port::new());
loop {
port_a.add_value(1);
port_b.add_value(2);
port_a.chain_port(port_b.clone());
for val in port_a.iter() {
// read data
};
port_a.clear();
port_b.clear();
}
}
However, the compiler complains:
error[E0596]: cannot borrow data in an `Rc` as mutable
--> src/modeling/port.rs:46:9
|
46 | port_a.add_value(1);
| ^^^^^^ cannot borrow as mutable
|
= help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Rc<Port<i32>>`
I've been reading several posts etc., and it seems that I need to work with Rc<RefCell<Port<T>>> to be able to mutate the ports. I changed the implementation of Port<T>:
use std::cell::RefCell;
use std::rc::Rc;
pub struct Port<T> {
values: Vec<T>,
ports: Vec<Rc<RefCell<Port<T>>>>,
}
impl<T> Port<T> {
// snip
pub fn chain_port(&mut self, port: Rc<RefCell<Port<T>>>) {
if !port.borrow().is_empty() {
self.ports.push(port)
}
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.values.iter().chain(
self.ports
.iter()
.flat_map(|p| Box::new(p.borrow().iter()) as Box<dyn Iterator<Item = &T>>),
)
}
// snip
}
This does not compile either:
error[E0515]: cannot return value referencing temporary value
--> src/modeling/port.rs:35:31
|
35 | .flat_map(|p| Box::new(p.borrow().iter()) as Box<dyn Iterator<Item = &T>>),
| ^^^^^^^^^----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | temporary value created here
| returns a value referencing data owned by the current function
I think I know what the problem is: p.borrow() returns a reference to the port being chained. We use that reference to create the iterator, but as soon as the function is done, the reference goes out of scope and the iterator is no longer valid.
I have no clue on how to deal with this. I managed to implement the following unsafe method:
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.values.iter().chain(self.ports.iter().flat_map(|p| {
Box::new(unsafe { (&*p.as_ref().as_ptr()).iter() }) as Box<dyn Iterator<Item = &T>>
}))
}
While this works, it uses unsafe code, and there must be a safe workaround.
I set a playground for more details of my application. The application compiles and outputs the expected result (but uses unsafe code).
You can't modify anything behind an Rc, that's correct. While this might be solved with a RefCell, you don't want to go down that road. You might come into a situation where you'd need to enforce a specific clean() order or similar horrors.
More important: your main is fundamentally flawed, ownership-wise. Take these lines:
let mut port_a = Port::new();
let mut port_b = Port::new();
loop {
// Creates an iummutable borrow of port_b with same lifetime as port_a!
port_a.chain_port(port_b);
// ...
// A mutable borrow of port_b.
// But the immutable borrow from above persists across iterations.
port_b.clear();
// Or, even if you do fancy shenanigans at least until this line.
port_a.clear();
}
To overcome this, just constrain the ports lifetime to one iteration. You currently manually clean them up anyway, so that's already what you're doing conceptually.
Also, I got rid of that recursive iteration, just to simplify things a little more.
#[derive(Clone)]
pub struct Port<'a, T> {
values: Vec<T>,
ports: Vec<&'a Port<'a, T>>,
}
impl<'a, T> Port<'a, T> {
pub fn new() -> Self {
Self {
values: vec![],
ports: vec![],
}
}
pub fn add_value(&mut self, value: T) {
self.values.push(value);
}
pub fn is_empty(&self) -> bool {
self.values.is_empty() && self.ports.is_empty()
}
pub fn chain_port(&mut self, port: &'a Port<T>) {
if !port.is_empty() {
self.ports.push(&port)
}
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
let mut port_stack: Vec<&Port<T>> = vec![self];
// Sensible estimate I guess.
let mut values: Vec<&T> = Vec::with_capacity(self.values.len() * (self.ports.len() + 1));
while let Some(port) = port_stack.pop() {
values.append(&mut port.values.iter().collect());
port_stack.extend(port.ports.iter());
}
values.into_iter()
}
}
fn main() {
loop {
let mut port_a = Port::new();
let mut port_b = Port::new();
port_a.add_value(1);
port_b.add_value(2);
port_a.chain_port(&port_b);
print!("values in port_a: [ ");
for val in port_a.iter() {
print!("{} ", val);
}
println!("]");
}
}
Say I have a struct whose implementation writes somewhere, i.e. to something that implements the std::io::Write trait. However, I don't want the struct to own this. The following code works:
fn main() {
let mut out = std::io::stdout();
let mut foo = Foo::new(&mut out);
foo.print_number(2);
}
struct Foo<'a> {
out: &'a mut dyn std::io::Write
}
impl<'a> Foo<'a> {
pub fn new(out: &'a mut dyn std::io::Write) -> Self {
Self {
out
}
}
pub fn print_number(&mut self, i: isize) {
writeln!(self.out, "The number is {}", i).unwrap()
}
}
But, now this writing functionality should be made optional. I thought this sounds easy enough, but now the following doesn't compile:
fn main() {
let mut out = std::io::stdout();
let mut foo = Foo::new(Some(&mut out));
foo.print_number(2);
}
struct Foo<'a> {
out: Option<&'a mut dyn std::io::Write>
}
impl<'a> Foo<'a> {
pub fn new(out: Option<&'a mut dyn std::io::Write>) -> Self {
Self {
out
}
}
pub fn print_number(&mut self, i: isize) {
if self.out.is_some() {
writeln!(self.out.unwrap(), "The number is {}", i).unwrap()
}
}
}
because of:
error[E0507]: cannot move out of `self.out` which is behind a mutable reference
--> src/main.rs:20:26
|
20 | writeln!(self.out.unwrap(), "The number is {}", i).unwrap()
| ^^^^^^^^
| |
| move occurs because `self.out` has type `Option<&mut dyn std::io::Write>`, which does not implement the `Copy` trait
| help: consider borrowing the `Option`'s content: `self.out.as_ref()`
which I'm not sure how to interpret.
I tried following the suggestion by changing the line in question to:
writeln!(self.out.as_ref().unwrap(), "The number is {}", i).unwrap()
but then I get
error[E0596]: cannot borrow data in a `&` reference as mutable
--> src/main.rs:20:26
|
20 | writeln!(self.out.as_ref().unwrap(), "The number is {}", i).unwrap()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
I'm really not sure how to interpret these error messages and surprisingly I'm not really getting anywhere by just sprinkling &s and muts in random places without really understanding!
(As an aside, I'm not sure if this is a "good" way of going about this anyway? I'm open to completely different approaches of solving this problem, which is basically to optionally pass something to write to into a struct, but without the struct owning it. I read about the Box type which might also be relevant?)
As you already know, based on you already using &mut for out. The issue with using as_ref() is that it returns an immutable reference. Instead you need to use as_mut().
pub fn print_number(&mut self, i: isize) {
if self.out.is_some() {
writeln!(self.out.as_mut().unwrap(), "The number is {}", i).unwrap()
}
}
Alternatively, you can also simplify this and express it more idiomatically using if let:
pub fn print_number(&mut self, i: isize) {
if let Some(out) = &mut self.out {
writeln!(out, "The number is {}", i).unwrap()
}
}
I would also suggest that instead of unwrapping, that you return the io::Result and let the caller handle any potential error.
pub fn print_number(&mut self, i: isize) -> std::io::Result<()> {
if let Some(out) = &mut self.out {
writeln!(out, "The number is {}", i)?;
}
Ok(())
}
You can also simplify your paths, e.g. std::io::Write and std::io::Result<()>, by importing them with a use declaration, e.g. use std::io::{self, Write}; and then changing them to Write and io::Result<()>.
I have code that works, but it stops compiling with a borrow checker error after a change. I don't understand how the change could affect borrow checking.
Common part to both working and non-working code:
/// Some struct that has references inside
#[derive(Debug)]
struct MyValue<'a> {
number: &'a u32,
}
/// There are many structs similar to `MyValue` and there is a
/// trait common to them all that can create them. In this
/// example I use the `From` trait.
impl<'a> From<&'a u32> for MyValue<'a> {
fn from(value: &'a u32) -> Self {
MyValue { number: value }
}
}
/// `Producer` makes objects that hold references into it. So
/// the produced object must be first dropped before any new
/// one can be made.
trait Producer<'a, T: 'a> {
fn make(&'a mut self) -> T;
}
Here is the working code:
struct MyProducer {
number: u32,
}
impl MyProducer {
fn new() -> Self {
Self { number: 0 }
}
}
impl<'a, T: 'a + From<&'a u32>> Producer<'a, T> for MyProducer {
fn make(&'a mut self) -> T {
self.number += 1;
T::from(&self.number)
}
}
fn main() {
let mut producer = MyProducer::new();
println!(
"made this: {:?}",
<MyProducer as Producer<MyValue>>::make(&mut producer)
);
println!(
"made this: {:?}",
<MyProducer as Producer<MyValue>>::make(&mut producer)
);
}
This compiles and prints the expected output:
made this: MyValue { number: 1 }
made this: MyValue { number: 2 }
I don't like that MyProducer actually implements Producer for every T as it makes it impossible to call make directly on it. I would like to have a type that is a MyProducer for a specific T (for example for MyValue).
To achieve this, I want to add a generic parameter to MyProducer. Because the MyProducer does not really use the T, I use PhantomData to prevent the compiler from complaining.
Here is the code after changes:
use std::marker::PhantomData;
struct MyProducer<'a, T: 'a + From<&'a u32>> {
number: u32,
_phantom: PhantomData<&'a T>,
}
impl<'a, T: 'a + From<&'a u32>> MyProducer<'a, T> {
fn new() -> Self {
Self {
number: 0,
_phantom: PhantomData::default(),
}
}
}
impl<'a, T: From<&'a u32>> Producer<'a, T> for MyProducer<'a, T> {
fn make(&'a mut self) -> T {
self.number += 1;
T::from(&self.number)
}
}
fn main() {
let mut producer = MyProducer::<MyValue>::new();
println!("made this: {:?}", producer.make());
println!("made this: {:?}", producer.make());
}
The main function now looks exactly as I would like it to look like. But the code does not compile. This is the error:
error[E0499]: cannot borrow `producer` as mutable more than once at a time
--> src/main.rs:50:33
|
49 | println!("made this: {:?}", producer.make());
| -------- first mutable borrow occurs here
50 | println!("made this: {:?}", producer.make());
| ^^^^^^^^
| |
| second mutable borrow occurs here
| first borrow later used here
I don't understand why it no longer works. The produced object is still dropped before the next one is made.
If I call the make function just once, it compiles and works.
I am using edition 2018, so NLL is active.
Rust Playground: working version before change
Rust Playground: broken version after change
I reduced the noise from the code so the following is an even shorter version of the broken case which demonstrates the same problem: (test in the playground)
use std::marker::PhantomData;
#[derive(Debug)]
struct MyValue<'a>(&'a u32);
impl<'a> From<&'a u32> for MyValue<'a> {
fn from(value: &'a u32) -> Self {
MyValue(value)
}
}
struct MyProducer<'a, T>(u32, PhantomData<&'a T>);
impl<'a, T> MyProducer<'a, T>
where
T: From<&'a u32>,
{
fn new() -> Self {
Self(0, PhantomData)
}
fn make(&'a mut self) -> T {
self.0 += 1;
T::from(&self.0)
}
}
fn main() {
let mut producer = MyProducer::<MyValue>::new();
println!("made this: {:?}", producer.make());
println!("made this: {:?}", producer.make());
}
The main problem here is that the mutable borrow's lifetime is the lifetime of MyProducer, that is, the lifetime of the instance called producer is the same as the mutable borrow taken in its make method. Because the producer instance does not go out of scope (if it would then MyValue wouldn't be able to hold a reference to a value stored in it) so the mutable borrow lives until the end of main's scope. The first rule of borrowing is that there can only be a single mutable borrow of a given value in a scope at any time, hence the compiler error.
If you are looking at my solution here, which is actually working and does what I think you wanted it to: (test in the playground):
#[derive(Debug)]
struct MyValue<'a>(&'a u32);
impl<'a> From<&'a u32> for MyValue<'a> {
fn from(value: &'a u32) -> Self {
MyValue(value)
}
}
struct MyProducer(u32);
impl MyProducer {
fn new() -> Self {
Self(0)
}
fn make<'a, T>(&'a mut self) -> T
where
T: From<&'a u32>,
{
self.0 += 1;
T::from(&self.0)
}
}
fn main() {
let mut producer = MyProducer::new();
println!("made this: {:?}", producer.make::<MyValue>());
println!("made this: {:?}", producer.make::<MyValue>());
}
then you can see that the mutable borrow only lives as long as the make method, therefore after the invocation there's no more living mutable borrow to producer in main's scope, thus you can have another one.