From 0f44350f32dc73396f66ef2dc113fb915cd885be Mon Sep 17 00:00:00 2001 From: KAUSTUBHOG Date: Mon, 10 Nov 2025 23:06:05 +0530 Subject: [PATCH 1/6] docs: clarify comment in owned_mutation test (fix #2303) --- exercises/19_smart_pointers/cow1.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/19_smart_pointers/cow1.rs b/exercises/19_smart_pointers/cow1.rs index 1566500716..0d075ab787 100644 --- a/exercises/19_smart_pointers/cow1.rs +++ b/exercises/19_smart_pointers/cow1.rs @@ -57,9 +57,9 @@ mod tests { #[test] fn owned_mutation() { - // Of course this is also the case if a mutation does occur (not all - // numbers are absolute). In this case, the call to `to_mut()` in the - // `abs_all` function returns a reference to the same data as before. + // When the data is already owned, even if a mutation occurs, `to_mut()` + // simply returns a mutable reference to the existing owned data without + // performing any clone. let vec = vec![-1, 0, 1]; let mut input = Cow::from(vec); abs_all(&mut input); From 0efc3c5b065f3b5e908e443bcd3475f458216b40 Mon Sep 17 00:00:00 2001 From: KAUSTUBHOG Date: Mon, 10 Nov 2025 23:45:07 +0530 Subject: [PATCH 2/6] fix: split Queue fields and clone sender in threads3.rs (fix #2268) --- exercises/20_threads/threads3.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/exercises/20_threads/threads3.rs b/exercises/20_threads/threads3.rs index 6d16bd9fec..b0fe8658df 100644 --- a/exercises/20_threads/threads3.rs +++ b/exercises/20_threads/threads3.rs @@ -15,20 +15,28 @@ impl Queue { } fn send_tx(q: Queue, tx: mpsc::Sender) { - // TODO: We want to send `tx` to both threads. But currently, it is moved - // into the first thread. How could you solve this problem? + // Destructure the Queue to move first_half and second_half independently + let Queue { + first_half, + second_half, + } = q; + + // Clone the sender so both threads can send to the same receiver + let tx1 = tx.clone(); + let tx2 = tx; + thread::spawn(move || { - for val in q.first_half { + for val in first_half { println!("Sending {val:?}"); - tx.send(val).unwrap(); + tx1.send(val).unwrap(); thread::sleep(Duration::from_millis(250)); } }); thread::spawn(move || { - for val in q.second_half { + for val in second_half { println!("Sending {val:?}"); - tx.send(val).unwrap(); + tx2.send(val).unwrap(); thread::sleep(Duration::from_millis(250)); } }); @@ -57,4 +65,4 @@ mod tests { received.sort(); assert_eq!(received, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); } -} +} \ No newline at end of file From 2cab96be521ccd428c5d2bdf811b6e69c2b184a5 Mon Sep 17 00:00:00 2001 From: KAUSTUBHOG Date: Mon, 10 Nov 2025 23:53:46 +0530 Subject: [PATCH 3/6] fix: keep TODO comment for learner guidance --- exercises/20_threads/threads3.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/exercises/20_threads/threads3.rs b/exercises/20_threads/threads3.rs index b0fe8658df..7bb3766872 100644 --- a/exercises/20_threads/threads3.rs +++ b/exercises/20_threads/threads3.rs @@ -15,6 +15,9 @@ impl Queue { } fn send_tx(q: Queue, tx: mpsc::Sender) { + // TODO: We want to send `tx` to both threads. But currently, it is moved + // into the first thread. How could you solve this problem? + // Destructure the Queue to move first_half and second_half independently let Queue { first_half, From a83950a0955501a2dc2c7404d9c5bab1b7517f58 Mon Sep 17 00:00:00 2001 From: KAUSTUBHOG Date: Mon, 10 Nov 2025 23:59:13 +0530 Subject: [PATCH 4/6] fix: add solution for threads3 ownership issue --- exercises/20_threads/threads3.rs | 3 --- solutions/20_threads/threads3.rs | 24 +++++++++++++++--------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/exercises/20_threads/threads3.rs b/exercises/20_threads/threads3.rs index 7bb3766872..b0fe8658df 100644 --- a/exercises/20_threads/threads3.rs +++ b/exercises/20_threads/threads3.rs @@ -15,9 +15,6 @@ impl Queue { } fn send_tx(q: Queue, tx: mpsc::Sender) { - // TODO: We want to send `tx` to both threads. But currently, it is moved - // into the first thread. How could you solve this problem? - // Destructure the Queue to move first_half and second_half independently let Queue { first_half, diff --git a/solutions/20_threads/threads3.rs b/solutions/20_threads/threads3.rs index 7ceefea016..b0fe8658df 100644 --- a/solutions/20_threads/threads3.rs +++ b/solutions/20_threads/threads3.rs @@ -15,22 +15,28 @@ impl Queue { } fn send_tx(q: Queue, tx: mpsc::Sender) { - // Clone the sender `tx` first. - let tx_clone = tx.clone(); + // Destructure the Queue to move first_half and second_half independently + let Queue { + first_half, + second_half, + } = q; + + // Clone the sender so both threads can send to the same receiver + let tx1 = tx.clone(); + let tx2 = tx; + thread::spawn(move || { - for val in q.first_half { + for val in first_half { println!("Sending {val:?}"); - // Then use the clone in the first thread. This means that - // `tx_clone` is moved to the first thread and `tx` to the second. - tx_clone.send(val).unwrap(); + tx1.send(val).unwrap(); thread::sleep(Duration::from_millis(250)); } }); thread::spawn(move || { - for val in q.second_half { + for val in second_half { println!("Sending {val:?}"); - tx.send(val).unwrap(); + tx2.send(val).unwrap(); thread::sleep(Duration::from_millis(250)); } }); @@ -59,4 +65,4 @@ mod tests { received.sort(); assert_eq!(received, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); } -} +} \ No newline at end of file From 2e9462fe1ae9f1fa845a3ec134c891c0426f784e Mon Sep 17 00:00:00 2001 From: KAUSTUBHOG Date: Tue, 11 Nov 2025 00:01:45 +0530 Subject: [PATCH 5/6] fix: add solution for threads3 ownership issue --- solutions/20_threads/threads3.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/20_threads/threads3.rs b/solutions/20_threads/threads3.rs index b0fe8658df..03c5f6b390 100644 --- a/solutions/20_threads/threads3.rs +++ b/solutions/20_threads/threads3.rs @@ -65,4 +65,4 @@ mod tests { received.sort(); assert_eq!(received, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); } -} \ No newline at end of file +} From 0df7d4b9dcb94b067b6dc52b8d770ead5a5eec22 Mon Sep 17 00:00:00 2001 From: KAUSTUBHOG Date: Tue, 11 Nov 2025 00:02:52 +0530 Subject: [PATCH 6/6] fix: revert exercise to unsolved state --- exercises/20_threads/threads3.rs | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/exercises/20_threads/threads3.rs b/exercises/20_threads/threads3.rs index b0fe8658df..6d16bd9fec 100644 --- a/exercises/20_threads/threads3.rs +++ b/exercises/20_threads/threads3.rs @@ -15,28 +15,20 @@ impl Queue { } fn send_tx(q: Queue, tx: mpsc::Sender) { - // Destructure the Queue to move first_half and second_half independently - let Queue { - first_half, - second_half, - } = q; - - // Clone the sender so both threads can send to the same receiver - let tx1 = tx.clone(); - let tx2 = tx; - + // TODO: We want to send `tx` to both threads. But currently, it is moved + // into the first thread. How could you solve this problem? thread::spawn(move || { - for val in first_half { + for val in q.first_half { println!("Sending {val:?}"); - tx1.send(val).unwrap(); + tx.send(val).unwrap(); thread::sleep(Duration::from_millis(250)); } }); thread::spawn(move || { - for val in second_half { + for val in q.second_half { println!("Sending {val:?}"); - tx2.send(val).unwrap(); + tx.send(val).unwrap(); thread::sleep(Duration::from_millis(250)); } }); @@ -65,4 +57,4 @@ mod tests { received.sort(); assert_eq!(received, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); } -} \ No newline at end of file +}