merged version 3
This commit is contained in:
@@ -345,13 +345,10 @@ machine for the generator defined aboce.</p>
|
|||||||
<p>We step through each step "manually" in every example, so it looks pretty
|
<p>We step through each step "manually" in every example, so it looks pretty
|
||||||
unfamiliar. We could add some syntactic sugar like implementing the <code>Iterator</code>
|
unfamiliar. We could add some syntactic sugar like implementing the <code>Iterator</code>
|
||||||
trait for our generators which would let us do this:</p>
|
trait for our generators which would let us do this:</p>
|
||||||
<pre><pre class="playpen"><code class="language-rust ingore">
|
<pre><code class="language-rust ignore">for val in generator {
|
||||||
# #![allow(unused_variables)]
|
|
||||||
#fn main() {
|
|
||||||
for val in generator {
|
|
||||||
println!("{}", val);
|
println!("{}", val);
|
||||||
}
|
}
|
||||||
#}</code></pre></pre>
|
</code></pre>
|
||||||
<p>It's a pretty trivial change to make, but this chapter is already getting long.
|
<p>It's a pretty trivial change to make, but this chapter is already getting long.
|
||||||
Just keep this in the back of your head as we move forward.</p>
|
Just keep this in the back of your head as we move forward.</p>
|
||||||
<p>Now what does our rewritten state machine look like with this example?</p>
|
<p>Now what does our rewritten state machine look like with this example?</p>
|
||||||
@@ -556,7 +553,9 @@ one huge problem with this:</p>
|
|||||||
</code></pre></pre>
|
</code></pre></pre>
|
||||||
<p>The problem however is that in safe Rust we can still do this:</p>
|
<p>The problem however is that in safe Rust we can still do this:</p>
|
||||||
<p><em>Run the code and compare the results. Do you see the problem?</em></p>
|
<p><em>Run the code and compare the results. Do you see the problem?</em></p>
|
||||||
<pre><pre class="playpen"><code class="language-rust">pub fn main() {
|
<pre><pre class="playpen"><code class="language-rust should_panic"># #![feature(never_type)] // Force nightly compiler to be used in playground
|
||||||
|
# // by betting on it's true that this type is named after it's stabilization date...
|
||||||
|
pub fn main() {
|
||||||
let mut gen = GeneratorA::start();
|
let mut gen = GeneratorA::start();
|
||||||
let mut gen2 = GeneratorA::start();
|
let mut gen2 = GeneratorA::start();
|
||||||
|
|
||||||
@@ -631,10 +630,15 @@ one huge problem with this:</p>
|
|||||||
# }
|
# }
|
||||||
</code></pre></pre>
|
</code></pre></pre>
|
||||||
<p>Wait? What happened to "Hello"?</p>
|
<p>Wait? What happened to "Hello"?</p>
|
||||||
<p>Turns out that while the example above compiles
|
<p>Turns out that while the example above compiles just fine, we expose consumers
|
||||||
just fine, we expose consumers of this this API to both possible undefined
|
of this this API to both possible undefined behavior and other memory errors
|
||||||
behavior and other memory errors while using just safe Rust. This is a big
|
while using just safe Rust. This is a big problem!</p>
|
||||||
problem!</p>
|
<blockquote>
|
||||||
|
<p>I've actually forced the code above to use the nightly version of the compiler.
|
||||||
|
If you run <a href="https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5cbe9897c0e23a502afd2740c7e78b98">the example above on the playground</a>,
|
||||||
|
you'll see that it runs without panic on the current stable (1.42.0) but
|
||||||
|
panics on the current nightly (1.44.0). Scary!</p>
|
||||||
|
</blockquote>
|
||||||
<p>We'll explain exactly what happened using a slightly simpler example in the next
|
<p>We'll explain exactly what happened using a slightly simpler example in the next
|
||||||
chapter and we'll fix our generator using <code>Pin</code> so join me as we explore
|
chapter and we'll fix our generator using <code>Pin</code> so join me as we explore
|
||||||
the last topic before we implement our main Futures example.</p>
|
the last topic before we implement our main Futures example.</p>
|
||||||
|
|||||||
@@ -746,7 +746,7 @@ impl Generator for GeneratorA {
|
|||||||
// the `String` earlier since these references will point to the
|
// the `String` earlier since these references will point to the
|
||||||
// location in this stack frame which will not be valid anymore
|
// location in this stack frame which will not be valid anymore
|
||||||
// when this function returns.
|
// when this function returns.
|
||||||
if let GeneratorA::Yield1 {to_borrow, borrowed} = self {
|
if let GeneratorA::Yield1 {to_borrow, borrowed} = this {
|
||||||
*borrowed = to_borrow;
|
*borrowed = to_borrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1175,13 +1175,10 @@ machine for the generator defined aboce.</p>
|
|||||||
<p>We step through each step "manually" in every example, so it looks pretty
|
<p>We step through each step "manually" in every example, so it looks pretty
|
||||||
unfamiliar. We could add some syntactic sugar like implementing the <code>Iterator</code>
|
unfamiliar. We could add some syntactic sugar like implementing the <code>Iterator</code>
|
||||||
trait for our generators which would let us do this:</p>
|
trait for our generators which would let us do this:</p>
|
||||||
<pre><pre class="playpen"><code class="language-rust ingore">
|
<pre><code class="language-rust ignore">for val in generator {
|
||||||
# #![allow(unused_variables)]
|
|
||||||
#fn main() {
|
|
||||||
for val in generator {
|
|
||||||
println!("{}", val);
|
println!("{}", val);
|
||||||
}
|
}
|
||||||
#}</code></pre></pre>
|
</code></pre>
|
||||||
<p>It's a pretty trivial change to make, but this chapter is already getting long.
|
<p>It's a pretty trivial change to make, but this chapter is already getting long.
|
||||||
Just keep this in the back of your head as we move forward.</p>
|
Just keep this in the back of your head as we move forward.</p>
|
||||||
<p>Now what does our rewritten state machine look like with this example?</p>
|
<p>Now what does our rewritten state machine look like with this example?</p>
|
||||||
@@ -1386,7 +1383,9 @@ one huge problem with this:</p>
|
|||||||
</code></pre></pre>
|
</code></pre></pre>
|
||||||
<p>The problem however is that in safe Rust we can still do this:</p>
|
<p>The problem however is that in safe Rust we can still do this:</p>
|
||||||
<p><em>Run the code and compare the results. Do you see the problem?</em></p>
|
<p><em>Run the code and compare the results. Do you see the problem?</em></p>
|
||||||
<pre><pre class="playpen"><code class="language-rust">pub fn main() {
|
<pre><pre class="playpen"><code class="language-rust should_panic"># #![feature(never_type)] // Force nightly compiler to be used in playground
|
||||||
|
# // by betting on it's true that this type is named after it's stabilization date...
|
||||||
|
pub fn main() {
|
||||||
let mut gen = GeneratorA::start();
|
let mut gen = GeneratorA::start();
|
||||||
let mut gen2 = GeneratorA::start();
|
let mut gen2 = GeneratorA::start();
|
||||||
|
|
||||||
@@ -1461,10 +1460,15 @@ one huge problem with this:</p>
|
|||||||
# }
|
# }
|
||||||
</code></pre></pre>
|
</code></pre></pre>
|
||||||
<p>Wait? What happened to "Hello"?</p>
|
<p>Wait? What happened to "Hello"?</p>
|
||||||
<p>Turns out that while the example above compiles
|
<p>Turns out that while the example above compiles just fine, we expose consumers
|
||||||
just fine, we expose consumers of this this API to both possible undefined
|
of this this API to both possible undefined behavior and other memory errors
|
||||||
behavior and other memory errors while using just safe Rust. This is a big
|
while using just safe Rust. This is a big problem!</p>
|
||||||
problem!</p>
|
<blockquote>
|
||||||
|
<p>I've actually forced the code above to use the nightly version of the compiler.
|
||||||
|
If you run <a href="https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5cbe9897c0e23a502afd2740c7e78b98">the example above on the playground</a>,
|
||||||
|
you'll see that it runs without panic on the current stable (1.42.0) but
|
||||||
|
panics on the current nightly (1.44.0). Scary!</p>
|
||||||
|
</blockquote>
|
||||||
<p>We'll explain exactly what happened using a slightly simpler example in the next
|
<p>We'll explain exactly what happened using a slightly simpler example in the next
|
||||||
chapter and we'll fix our generator using <code>Pin</code> so join me as we explore
|
chapter and we'll fix our generator using <code>Pin</code> so join me as we explore
|
||||||
the last topic before we implement our main Futures example.</p>
|
the last topic before we implement our main Futures example.</p>
|
||||||
@@ -2109,7 +2113,7 @@ impl Generator for GeneratorA {
|
|||||||
// the `String` earlier since these references will point to the
|
// the `String` earlier since these references will point to the
|
||||||
// location in this stack frame which will not be valid anymore
|
// location in this stack frame which will not be valid anymore
|
||||||
// when this function returns.
|
// when this function returns.
|
||||||
if let GeneratorA::Yield1 {to_borrow, borrowed} = self {
|
if let GeneratorA::Yield1 {to_borrow, borrowed} = this {
|
||||||
*borrowed = to_borrow;
|
*borrowed = to_borrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -222,7 +222,7 @@ We step through each step "manually" in every example, so it looks pretty
|
|||||||
unfamiliar. We could add some syntactic sugar like implementing the `Iterator`
|
unfamiliar. We could add some syntactic sugar like implementing the `Iterator`
|
||||||
trait for our generators which would let us do this:
|
trait for our generators which would let us do this:
|
||||||
|
|
||||||
```rust, ingore
|
```rust, ignore
|
||||||
for val in generator {
|
for val in generator {
|
||||||
println!("{}", val);
|
println!("{}", val);
|
||||||
}
|
}
|
||||||
@@ -447,7 +447,9 @@ pub fn main() {
|
|||||||
The problem however is that in safe Rust we can still do this:
|
The problem however is that in safe Rust we can still do this:
|
||||||
|
|
||||||
_Run the code and compare the results. Do you see the problem?_
|
_Run the code and compare the results. Do you see the problem?_
|
||||||
```rust
|
```rust, should_panic
|
||||||
|
# #![feature(never_type)] // Force nightly compiler to be used in playground
|
||||||
|
# // by betting on it's true that this type is named after it's stabilization date...
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let mut gen = GeneratorA::start();
|
let mut gen = GeneratorA::start();
|
||||||
let mut gen2 = GeneratorA::start();
|
let mut gen2 = GeneratorA::start();
|
||||||
@@ -525,10 +527,14 @@ pub fn main() {
|
|||||||
|
|
||||||
Wait? What happened to "Hello"?
|
Wait? What happened to "Hello"?
|
||||||
|
|
||||||
Turns out that while the example above compiles
|
Turns out that while the example above compiles just fine, we expose consumers
|
||||||
just fine, we expose consumers of this this API to both possible undefined
|
of this this API to both possible undefined behavior and other memory errors
|
||||||
behavior and other memory errors while using just safe Rust. This is a big
|
while using just safe Rust. This is a big problem!
|
||||||
problem!
|
|
||||||
|
> I've actually forced the code above to use the nightly version of the compiler.
|
||||||
|
> If you run [the example above on the playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5cbe9897c0e23a502afd2740c7e78b98),
|
||||||
|
> you'll see that it runs without panic on the current stable (1.42.0) but
|
||||||
|
> panics on the current nightly (1.44.0). Scary!
|
||||||
|
|
||||||
We'll explain exactly what happened using a slightly simpler example in the next
|
We'll explain exactly what happened using a slightly simpler example in the next
|
||||||
chapter and we'll fix our generator using `Pin` so join me as we explore
|
chapter and we'll fix our generator using `Pin` so join me as we explore
|
||||||
|
|||||||
@@ -652,7 +652,7 @@ impl Generator for GeneratorA {
|
|||||||
// the `String` earlier since these references will point to the
|
// the `String` earlier since these references will point to the
|
||||||
// location in this stack frame which will not be valid anymore
|
// location in this stack frame which will not be valid anymore
|
||||||
// when this function returns.
|
// when this function returns.
|
||||||
if let GeneratorA::Yield1 {to_borrow, borrowed} = self {
|
if let GeneratorA::Yield1 {to_borrow, borrowed} = this {
|
||||||
*borrowed = to_borrow;
|
*borrowed = to_borrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user