Skip to content
← All Rust tracks

Ownership II: Borrowing and the Borrow Checker

Rust

Use shared and mutable references to work with data without taking ownership. Learn to resolve conflicting borrows and choose appropriate function signatures.

This track uses Rust. You can make it your practice mode to browse related content across the site.

21 exercises

3 articles

Explore freely. Sign in to keep your progress.

Your learning sequence

  1. 1 Not solved yet. Move or borrow: the two ways to pass a value Practice · Easy
  2. 2 Not solved yet. &mut: exclusive access, and why mut appears twice Practice · Easy
  3. 3 Shared and mutable borrows Read
  4. 4 Not solved yet. How to read a borrow-check diagnostic Practice · Easy
  5. 5 Not solved yet. Non-lexical lifetimes: a borrow ends at its last use Practice · Easy
  6. 6 Not solved yet. E0502: cannot borrow as mutable because also borrowed as immutable Practice · Easy
  7. 7 Not solved yet. E0499: cannot borrow as mutable more than once Practice · Medium
  8. 8 Not solved yet. Accessing an owned value while it is borrowed Practice · Medium
  9. 9 Not solved yet. Slices are borrows Practice · Easy
  10. 10 Not solved yet. &str not &String, &[T] not &Vec<T>: deref coercion and ptr_arg Practice · Easy
  11. 11 Not solved yet. ref, ref mut, and default binding modes in edition 2024 Practice · Medium
  12. 12 Not solved yet. Remove matching values without invalidating iteration Practice · Medium
  13. 13 Not solved yet. Subtract the minimum with a mutable iterator Practice · Medium
  14. 14 Not solved yet. Carry a running maximum through mutable iteration Practice · Medium
  15. 15 Not solved yet. Split borrows: the checker reasons about places, not variables Practice · Medium
  16. 16 Not solved yet. split_at_mut and the disjointness-proof APIs Practice · Medium
  17. 17 Not solved yet. Reborrowing: why &mut sometimes moves and sometimes doesn't Practice · Hard
  18. 18 Not solved yet. Two-phase borrows: why v.push(v.len()) compiles Practice · Hard
  19. 19 Not solved yet. What a &mut parameter actually promises Practice · Medium
  20. 20 Not solved yet. Count words with the HashMap entry API Practice · Hard
  21. 21 Not solved yet. Closures hold their borrows Practice · Medium
  22. 22 Not solved yet. Share a log with RefCell and report borrow conflicts Practice · Medium
  23. 23 How borrowing helps the optimizer Read
  24. 24 Understanding borrow-checker errors Read

Check yourself

4 questions · not saved while you're signed out

Use these questions to check your understanding and compare explanations. Your score does not affect track completion.

0 / 4 correct

With rustc 1.95.0, why does insert trigger a borrowing error in this function?

Choose one answer to reveal the explanations. Answers are kept only while this page is open.

use std::collections::HashMap;

fn get_or_insert(map: &mut HashMap<u32, u32>, key: u32) -> &u32 {
    if let Some(value) = map.get(&key) {
        return value;
    }
    map.insert(key, 0);
    map.get(&key).unwrap()
}

fn main() {
    let mut map = HashMap::new();
    println!("{}", get_or_insert(&mut map, 7));
}
Question 1 of 4