diff --git a/src/1_2_generators_pin.md b/src/1_2_generators_pin.md index ddb3b39..55c4cb4 100644 --- a/src/1_2_generators_pin.md +++ b/src/1_2_generators_pin.md @@ -170,7 +170,7 @@ impl Generator for GeneratorA { match std::mem::replace(&mut *self, GeneratorA::Exit) { GeneratorA::Enter(a1) => { - /*|---code before yield1---|*/ + /*|---code before yield---|*/ /*|*/ println!("Hello"); /*|*/ /*|*/ let a = a1 * 2; /*|*/ /*|------------------------|*/ @@ -180,7 +180,7 @@ impl Generator for GeneratorA { } GeneratorA::Yield1(_) => { - /*|----code after yield1----|*/ + /*|----code after yield----|*/ /*|*/ println!("world!"); /*|*/ /*|-------------------------|*/ @@ -191,6 +191,7 @@ impl Generator for GeneratorA { } } } + ``` >The `yield` keyword was discussed first in [RFC#1823][rfc1823] and in [RFC#1832][rfc1832]. @@ -299,6 +300,7 @@ pub fn main() { if let GeneratorState::Yielded(n) = gen.resume() { println!("Got value {}", n); } + // If you uncomment this, very bad things can happen. This is why we need `Pin` // std::mem::swap(&mut gen, &mut gen2); diff --git a/src/1_3_pin.md b/src/1_3_pin.md index 932707f..f0cec04 100644 --- a/src/1_3_pin.md +++ b/src/1_3_pin.md @@ -149,29 +149,6 @@ If we change the example to using `Pin` instead: use std::pin::Pin; use std::marker::PhantomPinned; -pub fn main() { - let mut test1 = Test::new("test1"); - test1.init(); - let mut test1_pin = unsafe { Pin::new_unchecked(&mut test1) }; - let mut test2 = Test::new("test2"); - test2.init(); - let mut test2_pin = unsafe { Pin::new_unchecked(&mut test2) }; - - println!( - "a: {}, b: {}", - Test::a(test1_pin.as_ref()), - Test::b(test1_pin.as_ref()) - ); - - // Try to uncomment this and see what happens - // std::mem::swap(test1_pin.as_mut(), test2_pin.as_mut()); - println!( - "a: {}, b: {}", - Test::a(test2_pin.as_ref()), - Test::b(test2_pin.as_ref()) - ); -} - #[derive(Debug)] struct Test { a: String, @@ -204,6 +181,29 @@ impl Test { } } +pub fn main() { + let mut test1 = Test::new("test1"); + test1.init(); + let mut test1_pin = unsafe { Pin::new_unchecked(&mut test1) }; + let mut test2 = Test::new("test2"); + test2.init(); + let mut test2_pin = unsafe { Pin::new_unchecked(&mut test2) }; + + println!( + "a: {}, b: {}", + Test::a(test1_pin.as_ref()), + Test::b(test1_pin.as_ref()) + ); + + // Try to uncomment this and see what happens + // std::mem::swap(test1_pin.as_mut(), test2_pin.as_mut()); + println!( + "a: {}, b: {}", + Test::a(test2_pin.as_ref()), + Test::b(test2_pin.as_ref()) + ); +} + ``` Now, what we've done here is pinning a stack address. That will always be @@ -222,17 +222,6 @@ The next example solves some of our friction at the cost of a heap allocation. use std::pin::Pin; use std::marker::PhantomPinned; -pub fn main() { - let mut test1 = Test::new("test1"); - let mut test2 = Test::new("test2"); - - println!("a: {}, b: {}",test1.as_ref().a(), test1.as_ref().b()); - - // Try to uncomment this and see what happens - // std::mem::swap(&mut test1, &mut test2); - println!("a: {}, b: {}",test2.as_ref().a(), test2.as_ref().b()); -} - #[derive(Debug)] struct Test { a: String, @@ -263,6 +252,17 @@ impl Test { unsafe { &*(self.b) } } } + +pub fn main() { + let mut test1 = Test::new("test1"); + let mut test2 = Test::new("test2"); + + println!("a: {}, b: {}",test1.as_ref().a(), test1.as_ref().b()); + + // Try to uncomment this and see what happens + // std::mem::swap(&mut test1, &mut test2); + println!("a: {}, b: {}",test2.as_ref().a(), test2.as_ref().b()); +} ``` The fact that boxing (heap allocating) a value that implements `!Unpin` is safe