Simple example with Rcs and Refcells produces confusing compiler error

Hi there.

I'm trying to get comfortable w/ Rcs and RefCells. The compiler is unhappy with me; I'm stumped by this error message:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/
40 |             self.add_string(s)
   |                  ^^^^^^^^^^
note: first, the lifetime cannot outlive the lifetime `'_` as defined on the body at 39:28...
  --> src/
39 |         ss.into_iter().map(|s| {
   |                            ^^^
note: that closure can access `self`
  --> src/
40 |             self.add_string(s)
   |             ^^^^
note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the method body at 38:5...
  --> src/
38 |     pub fn add_strings(&mut self, ss: Vec<String>) -> Vec<&[String]> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: that the expression is assignable
  --> src/
39 | /         ss.into_iter().map(|s| {
40 | |             self.add_string(s)
41 | |         }).collect()
   | |____________________^
   = note: expected `Vec<&[String]>`
              found `Vec<&[String]>`

The minimal code snippet that generated that compiler error is below:

    use std::cell::RefCell;
    use std::rc::Rc;

    pub struct Foo {
        strings: Rc<RefCell<Vec<String>>>,
        message_log: Vec<String>

    impl Foo {
        fn add_message_to_log_and_print(&mut self, message: String) -> &[String] {
            let current_log_length = self.message_log.len();        
            println!("{:?}", message);
        pub fn add_string(&mut self, s: String) -> &[String] {
            let message = "Added a string!";

        pub fn add_strings(&mut self, ss: Vec<String>) -> Vec<&[String]> {
            ss.into_iter().map(|s| {

    fn main() {

Can someone help me understand what the compiler is telling me here? Thanks in advance!

This is because your add_strings method will call add_string multiple times, while keeping the returned reference from each call around. However each call to add_string might mutate self in a way that invalidates references returned by previous calls to it, e.g. the self.message_log.push(message); can cause the vector to reallocate, which would indeed break all previous references into that vector.

Note that when you have mutable access to a RefCell, you can use its get_mut method instead of borrow_mut, which cannot panic.


This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.