0

Trying to understand why merchant.add_cart() is complaining and merchant.add_product() is fine. Both Cart and Product contain more or less the same structure

use std::collections::HashMap;

#[derive(Debug, Clone)]
struct Merchant<'a> {
    id: u64,
    name: String,
    products: HashMap<u64, &'a Product>,
    carts: HashMap<u64, &'a Cart>,
}

impl<'a> Merchant<'a> {
    pub fn new(id: u64, name: String) -> Merchant<'a> {
        Merchant {
            id,
            name,
            products: HashMap::new(),
            carts: HashMap::new(),
        }
    }

    pub fn add_product(&mut self, product: &'a Product) {
        self.products.insert(product.id, product);
    }

    pub fn add_cart(&mut self, cart: &'a Cart) {
        self.carts.insert(cart.id, cart);
    }
}

#[derive(Debug, Clone)]
struct Product {
    id: u64,
    name: String,
    amount_in_cents: u64,
}

impl Product {
    pub fn new(id: u64, name: String, amount_in_cents: u64) -> Product {
        Product {
            id,
            name,
            amount_in_cents,
        }
    }
}

#[derive(Debug, Clone)]
struct Cart {
    id: u64,
}

impl Cart {
    pub fn new(id: u64) -> Cart {
        Cart { id }
    }
}

fn main() {
    let apple = Product::new(1, String::from("Apple"), 10000);
    let orange = Product::new(2, String::from("Orange"), 20000);
    let guava = Product::new(3, String::from("Guava"), 30000);

    let mut merchant = Merchant::new(1, String::from("Oak Market"));

    merchant.add_product(&apple);
    merchant.add_product(&orange);
    merchant.add_product(&guava);

    let cart = Cart::new(1);
    merchant.add_cart(&cart);
}

merchant.add_cart(&cart); is complaining with

cart does not live long enough: borrowed value does not live long enough

Using rustc 1.31.0

Christian Fazzini
  • 19,613
  • 21
  • 110
  • 215

1 Answers1

3

When I compile your code, the full error message is this:

   |
70 |     merchant.add_cart(&cart);
   |                        ^^^^ borrowed value does not live long enough
71 | }
   | - `cart` dropped here while still borrowed
   |
   = note: values in a scope are dropped in the opposite order they are created

That last line is telling you your problem. You declared apple, orange and guava before merchant, so they outlive merchant, and so it is okay to store references to them. However, you declare cart after merchant, so merchant outlives it, thus you are not able to store a reference to it.

Note that your code will compile in Rust 2018 edition, because of non-lexical-lifetimes, explained here.

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274