Bird
Raised Fist0
Rustprogramming~20 mins

Borrowing rules in Rust - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Rust Borrowing Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this Rust code with borrowing?

Consider the following Rust code snippet. What will it print?

Rust
fn main() {
    let mut s = String::from("hello");
    let r1 = &s;
    let r2 = &s;
    println!("{} and {}", r1, r2);
    let r3 = &mut s;
    r3.push_str(", world");
    println!("{}", r3);
}
ACompilation error due to mutable borrow while immutable borrows exist
Bhello and hello\nhello
Chello and hello\nhello, world
DRuntime panic due to simultaneous mutable and immutable borrows
Attempts:
2 left
💡 Hint

Remember Rust does not allow mutable borrow while immutable borrows are active.

❓ Predict Output
intermediate
2:00remaining
What does this Rust code print with multiple borrows?

Analyze the following Rust code. What is the output?

Rust
fn main() {
    let mut x = 5;
    let r1 = &x;
    let r2 = &x;
    println!("{} and {}", r1, r2);
    let r3 = &mut x;
    *r3 += 1;
    println!("{}", r3);
}
A5 and 5\n6
BRuntime panic due to mutable and immutable borrows
C5 and 5\n5
DCompilation error due to mutable borrow while immutable borrows exist
Attempts:
2 left
💡 Hint

Check when the immutable borrows end before the mutable borrow starts.

🔧 Debug
advanced
2:00remaining
Why does this Rust code fail to compile due to borrowing?

Identify the reason for the compilation error in this Rust code snippet.

Rust
fn main() {
    let mut s = String::from("hello");
    let r1 = &mut s;
    let r2 = &s;
    println!("{}", r2);
    r1.push_str(", world");
}
ACannot borrow `s` as mutable because it is already borrowed as immutable
BCannot borrow `s` as immutable because it is already borrowed as mutable
CUse of moved value `s`
DNo error, code runs and prints 'hello, world'
Attempts:
2 left
💡 Hint

Check the order and types of borrows on the variable s.

📝 Syntax
advanced
2:00remaining
Which option causes a compile-time error due to borrowing rules?

Given these Rust code snippets, which one will fail to compile because of borrowing rules?

Alet mut v = vec![1, 2, 3]; let r1 = &v; let r2 = &mut v; r2.push(4); println!("{:?}", r1);
Blet mut v = vec![1, 2, 3]; let r1 = &mut v; r1.push(4); println!("{:?}", r1);
Clet v = vec![1, 2, 3]; let r1 = &v; println!("{:?}", r1);
Dlet mut v = vec![1, 2, 3]; let r1 = &mut v; r1.push(4);
Attempts:
2 left
💡 Hint

Look for simultaneous mutable and immutable borrows.

🚀 Application
expert
2:00remaining
How many mutable references can exist simultaneously in Rust?

In Rust, how many mutable references to the same variable can exist at the same time without causing a compile error?

ANo mutable references allowed, only immutable
BTwo mutable references at a time
COnly one mutable reference at a time
DAny number of mutable references as long as no immutable references exist
Attempts:
2 left
💡 Hint

Recall Rust's exclusive mutable borrowing rule.

Practice

(1/5)
1. What does borrowing in Rust allow you to do?
easy
A. Copy data to a new variable
B. Use data without taking ownership
C. Delete data immediately
D. Create multiple owners of data

Solution

  1. Step 1: Understand borrowing concept

    Borrowing means using data without taking ownership, so the original owner keeps control.
  2. Step 2: Compare options

    Copying or deleting data changes ownership or data state, which borrowing does not do.
  3. Final Answer:

    Use data without taking ownership -> Option B
  4. Quick Check:

    Borrowing = Use without ownership [OK]
Hint: Borrowing means using data without owning it [OK]
Common Mistakes:
  • Confusing borrowing with copying
  • Thinking borrowing deletes data
  • Assuming borrowing creates multiple owners
2. Which of the following is the correct syntax to create an immutable borrow of a variable x in Rust?
easy
A. let y = &x;
B. let y = *x;
C. let y = &mut x;
D. let y = x;

Solution

  1. Step 1: Identify immutable borrow syntax

    Immutable borrow uses &x to create a reference without allowing changes.
  2. Step 2: Check other options

    &mut x is mutable borrow, *x dereferences, and x moves ownership.
  3. Final Answer:

    let y = &x; -> Option A
  4. Quick Check:

    Immutable borrow = &x [OK]
Hint: Immutable borrow uses & before variable [OK]
Common Mistakes:
  • Using &mut for immutable borrow
  • Dereferencing instead of borrowing
  • Assigning ownership instead of reference
3. What will be the output of this Rust code?
let mut s = String::from("hello");
let r1 = &s;
let r2 = &s;
println!("{} and {}", r1, r2);
let r3 = &mut s;
println!("{}", r3);
medium
A. hello and hello\nerror at runtime
B. hello and hello\nhello
C. Compile error due to mutable borrow while immutable borrows exist
D. hello\nhello and hello

Solution

  1. Step 1: Analyze immutable borrows

    Two immutable borrows r1 and r2 are allowed simultaneously.
  2. Step 2: Check mutable borrow after immutable borrows

    Trying to create mutable borrow r3 while immutable borrows exist causes compile error.
  3. Final Answer:

    Compile error due to mutable borrow while immutable borrows exist -> Option C
  4. Quick Check:

    Mutable borrow disallowed with active immutable borrows [OK]
Hint: No mutable borrow allowed if immutable borrows exist [OK]
Common Mistakes:
  • Assuming mutable borrow works after immutable borrows
  • Expecting runtime error instead of compile error
  • Confusing output with allowed borrows
4. Identify the error in this Rust code snippet:
let mut data = vec![1, 2, 3];
let r1 = &mut data;
let r2 = &data;
r1.push(4);
println!("{:?}", r2);
medium
A. No error, code runs fine
B. Cannot push to vector inside mutable borrow
C. Cannot print vector with {:?}
D. Cannot borrow data as immutable while mutable borrow exists

Solution

  1. Step 1: Check borrows

    Variable r1 is a mutable borrow, r2 is an immutable borrow of the same data.
  2. Step 2: Understand borrowing rules

    Rust forbids immutable borrow while mutable borrow is active, causing a compile error.
  3. Final Answer:

    Cannot borrow data as immutable while mutable borrow exists -> Option D
  4. Quick Check:

    Immutable borrow disallowed during mutable borrow [OK]
Hint: No immutable borrow allowed during mutable borrow [OK]
Common Mistakes:
  • Thinking push is invalid inside mutable borrow
  • Ignoring borrow conflict between r1 and r2
  • Assuming printing with {:?} causes error
5. You want to write a function that takes a mutable reference to a vector and appends a number, but also returns the length of the vector after appending. Which function signature and usage follow Rust's borrowing rules correctly?
hard
A. fn add_and_len(v: &mut Vec<i32>, n: i32) -> usize { v.push(n); v.len() } let mut nums = vec![1,2]; let length = add_and_len(&mut nums, 3);
B. fn add_and_len(v: &Vec<i32>, n: i32) -> usize { v.push(n); v.len() } let mut nums = vec![1,2]; let length = add_and_len(&nums, 3);
C. fn add_and_len(v: Vec<i32>, n: i32) -> usize { v.push(n); v.len() } let nums = vec![1,2]; let length = add_and_len(nums, 3);
D. fn add_and_len(v: &mut Vec<i32>, n: i32) -> usize { v.len(); v.push(n) } let mut nums = vec![1,2]; let length = add_and_len(&mut nums, 3);

Solution

  1. Step 1: Check function signature for mutable borrow

    Function needs &mut Vec<i32> to modify vector by pushing a number.
  2. Step 2: Verify function body and usage

    fn add_and_len(v: &mut Vec<i32>, n: i32) -> usize { v.push(n); v.len() } let mut nums = vec![1,2]; let length = add_and_len(&mut nums, 3); pushes number then returns length correctly; usage passes mutable reference.
  3. Step 3: Analyze other options

    fn add_and_len(v: &Vec<i32>, n: i32) -> usize { v.push(n); v.len() } let mut nums = vec![1,2]; let length = add_and_len(&nums, 3); uses immutable borrow but tries to push (not allowed). fn add_and_len(v: Vec<i32>, n: i32) -> usize { v.push(n); v.len() } let nums = vec![1,2]; let length = add_and_len(nums, 3); takes ownership, not borrow. fn add_and_len(v: &mut Vec<i32>, n: i32) -> usize { v.len(); v.push(n) } let mut nums = vec![1,2]; let length = add_and_len(&mut nums, 3); returns length before push, so length is old value.
  4. Final Answer:

    fn add_and_len(v: &mut Vec<i32>, n: i32) -> usize { v.push(n); v.len() } let mut nums = vec![1,2]; let length = add_and_len(&mut nums, 3); -> Option A
  5. Quick Check:

    Mutable borrow needed to modify vector [OK]
Hint: Use &mut to modify data inside function [OK]
Common Mistakes:
  • Using immutable borrow when modifying data
  • Taking ownership instead of borrowing
  • Returning length before modification
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard