fixed editions and ignoring

This commit is contained in:
funkill2 2019-11-19 14:09:41 +03:00 committed by Taylor Cramer
parent 658ce12b21
commit d7651bb1cd
14 changed files with 79 additions and 59 deletions

View File

@ -30,7 +30,7 @@ must register `wake` to be called when data becomes ready on the socket,
which will tell the executor that our future is ready to make progress.
A simple `SocketRead` future might look something like this:
```rust
```rust,ignore
{{#include ../../examples/02_02_future_trait/src/lib.rs:socket_read}}
```
@ -39,7 +39,7 @@ operations without needing intermediate allocations. Running multiple futures
at once or chaining futures together can be implemented via allocation-free
state machines, like this:
```rust
```rust,ignore
{{#include ../../examples/02_02_future_trait/src/lib.rs:join}}
```
@ -47,7 +47,7 @@ This shows how multiple futures can be run simultaneously without needing
separate allocations, allowing for more efficient asynchronous programs.
Similarly, multiple sequential futures can be run one after another, like this:
```rust
```rust,ignore
{{#include ../../examples/02_02_future_trait/src/lib.rs:and_then}}
```
@ -56,12 +56,12 @@ control flow without requiring multiple allocated objects and deeply nested
callbacks. With the basic control-flow out of the way, let's talk about the
real `Future` trait and how it is different.
```rust
```rust,ignore
{{#include ../../examples/02_02_future_trait/src/lib.rs:real_future}}
```
The first change you'll notice is that our `self` type is no longer `&mut self`,
but has changed to `Pin<&mut Self>`. We'll talk more about pinning in [a later
but has changed to `Pin<&mut Self>`. We'll talk more about pinning in [a later
section][pinning], but for now know that it allows us to create futures that
are immovable. Immovable objects can store pointers between their fields,
e.g. `struct MyFut { a: i32, ptr_to_a: *const i32 }`. Pinning is necessary

View File

@ -34,13 +34,13 @@ thread to communicate that the timer has elapsed and the future should complete.
We'll use a shared `Arc<Mutex<..>>` value to communicate between the thread and
the future.
```rust
```rust,ignore
{{#include ../../examples/02_03_timer/src/lib.rs:timer_decl}}
```
Now, let's actually write the `Future` implementation!
```rust
```rust,ignore
{{#include ../../examples/02_03_timer/src/lib.rs:future_for_timer}}
```
@ -55,7 +55,7 @@ being polled.
Finally, we need the API to actually construct the timer and start the thread:
```rust
```rust,ignore
{{#include ../../examples/02_03_timer/src/lib.rs:timer_new}}
```

View File

@ -32,7 +32,7 @@ futures = "0.3"
Next, we need the following imports at the top of `src/main.rs`:
```rust
```rust,ignore
{{#include ../../examples/02_04_executor/src/lib.rs:imports}}
```
@ -47,7 +47,7 @@ Tasks themselves are just futures that can reschedule themselves, so we'll
store them as a future paired with a sender that the task can use to requeue
itself.
```rust
```rust,ignore
{{#include ../../examples/02_04_executor/src/lib.rs:executor_decl}}
```
@ -56,7 +56,7 @@ This method will take a future type, box it and put it in a FutureObj,
and create a new `Arc<Task>` with it inside which can be enqueued onto the
executor.
```rust
```rust,ignore
{{#include ../../examples/02_04_executor/src/lib.rs:spawn_fn}}
```
@ -70,7 +70,7 @@ the `waker_ref` or `.into_waker()` functions to turn an `Arc<impl ArcWake>`
into a `Waker`. Let's implement `ArcWake` for our tasks to allow them to be
turned into `Waker`s and awoken:
```rust
```rust,ignore
{{#include ../../examples/02_04_executor/src/lib.rs:arcwake_for_task}}
```
@ -78,7 +78,7 @@ When a `Waker` is created from an `Arc<Task>`, calling `wake()` on it will
cause a copy of the `Arc` to be sent onto the task channel. Our executor then
needs to pick up the task and poll it. Let's implement that:
```rust
```rust,ignore
{{#include ../../examples/02_04_executor/src/lib.rs:executor_run}}
```
@ -86,7 +86,7 @@ Congratulations! We now have a working futures executor. We can even use it
to run `async/.await` code and custom futures, such as the `TimerFuture` we
wrote earlier:
```rust
```rust,edition2018,ignore
{{#include ../../examples/02_04_executor/src/lib.rs:main}}
```

View File

@ -3,7 +3,7 @@
In the previous section on [The `Future` Trait], we discussed this example of
a future that performed an asynchronous read on a socket:
```rust
```rust,ignore
{{#include ../../examples/02_02_future_trait/src/lib.rs:socket_read}}
```
@ -26,9 +26,9 @@ a thread to block on multiple asynchronous IO events, returning once one of
the events completes. In practice, these APIs usually look something like
this:
```rust
```rust,ignore
struct IoBlocker {
...
/* ... */
}
struct Event {
@ -41,7 +41,7 @@ struct Event {
impl IoBlocker {
/// Create a new collection of asynchronous IO events to block on.
fn new() -> Self { ... }
fn new() -> Self { /* ... */ }
/// Express an interest in a particular IO event.
fn add_io_event_interest(
@ -54,10 +54,10 @@ impl IoBlocker {
/// which an event should be triggered, paired with
/// an ID to give to events that result from this interest.
event: Event,
) { ... }
) { /* ... */ }
/// Block until one of the events occurs.
fn block(&self) -> Event { ... }
fn block(&self) -> Event { /* ... */ }
}
let mut io_blocker = IoBlocker::new();
@ -80,7 +80,7 @@ such as sockets that can configure callbacks to be run when a particular IO
event occurs. In the case of our `SocketRead` example above, the
`Socket::set_readable_callback` function might look like the following pseudocode:
```rust
```rust,ignore
impl Socket {
fn set_readable_callback(&self, waker: Waker) {
// `local_executor` is a reference to the local executor.

View File

@ -12,7 +12,7 @@ code to make progress while waiting on an operation to complete.
There are two main ways to use `async`: `async fn` and `async` blocks.
Each returns a value that implements the `Future` trait:
```rust
```rust,edition2018,ignore
{{#include ../../examples/03_01_async_await/src/lib.rs:async_fn_and_block_examples}}
```
@ -29,7 +29,7 @@ Unlike traditional functions, `async fn`s which take references or other
non-`'static` arguments return a `Future` which is bounded by the lifetime of
the arguments:
```rust
```rust,edition2018,ignore
{{#include ../../examples/03_01_async_await/src/lib.rs:lifetimes_expanded}}
```
@ -43,7 +43,7 @@ One common workaround for turning an `async fn` with references-as-arguments
into a `'static` future is to bundle the arguments with the call to the
`async fn` inside an `async` block:
```rust
```rust,edition2018,ignore
{{#include ../../examples/03_01_async_await/src/lib.rs:static_future_with_borrow}}
```
@ -57,7 +57,7 @@ closures. An `async move` block will take ownership of the variables it
references, allowing it to outlive the current scope, but giving up the ability
to share those variables with other code:
```rust
```rust,edition2018,ignore
{{#include ../../examples/03_01_async_await/src/lib.rs:async_move_examples}}
```

View File

@ -12,9 +12,9 @@ Pinning makes it possible to guarantee that an object won't ever be moved.
To understand why this is necessary, we need to remember how `async`/`.await`
works. Consider the following code:
```rust
let fut_one = ...;
let fut_two = ...;
```rust,edition2018,ignore
let fut_one = /* ... */;
let fut_two = /* ... */;
async move {
fut_one.await;
fut_two.await;
@ -24,7 +24,7 @@ async move {
Under the hood, this creates an anonymous type that implements `Future`,
providing a `poll` method that looks something like this:
```rust
```rust,ignore
// The `Future` type generated by our `async { ... }` block
struct AsyncFuture {
fut_one: FutOne,
@ -69,7 +69,7 @@ is able to successfully complete.
However, what happens if we have an `async` block that uses references?
For example:
```rust
```rust,edition2018,ignore
async {
let mut x = [0; 128];
let read_into_buf_fut = read_into_buf(&mut x);
@ -80,7 +80,7 @@ async {
What struct does this compile down to?
```rust
```rust,ignore
struct ReadIntoBuf<'a> {
buf: &'a mut [u8], // points to `x` below
}
@ -118,22 +118,22 @@ used as futures, and both implement `Unpin`.
For example:
```rust
```rust,edition2018,ignore
use pin_utils::pin_mut; // `pin_utils` is a handy crate available on crates.io
// A function which takes a `Future` that implements `Unpin`.
fn execute_unpin_future(x: impl Future<Output = ()> + Unpin) { ... }
fn execute_unpin_future(x: impl Future<Output = ()> + Unpin) { /* ... */ }
let fut = async { ... };
let fut = async { /* ... */ };
execute_unpin_future(fut); // Error: `fut` does not implement `Unpin` trait
// Pinning with `Box`:
let fut = async { ... };
let fut = async { /* ... */ };
let fut = Box::pin(fut);
execute_unpin_future(fut); // OK
// Pinning with `pin_mut!`:
let fut = async { ... };
let fut = async { /* ... */ };
pin_mut!(fut);
execute_unpin_future(fut); // OK
```

View File

@ -3,7 +3,7 @@
The `Stream` trait is similar to `Future` but can yield multiple values before
completing, similar to the `Iterator` trait from the standard library:
```rust
```rust,ignore
{{#include ../../examples/05_01_streams/src/lib.rs:stream_trait}}
```
@ -12,6 +12,6 @@ the `futures` crate. It will yield `Some(val)` every time a value is sent
from the `Sender` end, and will yield `None` once the `Sender` has been
dropped and all pending messages have been received:
```rust
```rust,edition2018,ignore
{{#include ../../examples/05_01_streams/src/lib.rs:channels}}
```

View File

@ -9,7 +9,7 @@ Unfortunately, `for` loops are not usable with `Stream`s, but for
imperative-style code, `while let` and the `next`/`try_next` functions can
be used:
```rust
```rust,edition2018,ignore
{{#include ../../examples/05_02_iteration_and_concurrency/src/lib.rs:nexts}}
```
@ -19,6 +19,6 @@ writing async code in the first place. To process multiple items from a stream
concurrently, use the `for_each_concurrent` and `try_for_each_concurrent`
methods:
```rust
```rust,edition2018,ignore
{{#include ../../examples/05_02_iteration_and_concurrency/src/lib.rs:try_for_each_concurrent}}
```

View File

@ -8,7 +8,7 @@ futures to complete while executing them all concurrently.
When performing multiple asynchronous operations, it's tempting to simply
`.await` them in a series:
```rust
```rust,edition2018,ignore
{{#include ../../examples/06_02_join/src/lib.rs:naiive}}
```
@ -18,7 +18,7 @@ futures are ambiently run to completion, so two operations can be
run concurrently by first calling each `async fn` to start the futures, and
then awaiting them both:
```rust
```rust,edition2018,ignore
{{#include ../../examples/06_02_join/src/lib.rs:other_langs}}
```
@ -28,7 +28,7 @@ This means that the two code snippets above will both run
concurrently. To correctly run the two futures concurrently, use
`futures::join!`:
```rust
```rust,edition2018,ignore
{{#include ../../examples/06_02_join/src/lib.rs:join}}
```
@ -45,7 +45,7 @@ has returned an `Err`.
Unlike `join!`, `try_join!` will complete immediately if one of the subfutures
returns an error.
```rust
```rust,edition2018,ignore
{{#include ../../examples/06_02_join/src/lib.rs:try_join}}
```
@ -53,6 +53,6 @@ Note that the futures passed to `try_join!` must all have the same error type.
Consider using the `.map_err(|e| ...)` and `.err_into()` functions from
`futures::future::TryFutureExt` to consolidate the error types:
```rust
```rust,edition2018,ignore
{{#include ../../examples/06_02_join/src/lib.rs:try_join_map_err}}
```

View File

@ -3,7 +3,7 @@
The `futures::select` macro runs multiple futures simultaneously, allowing
the user to respond as soon as any future completes.
```rust
```rust,edition2018
{{#include ../../examples/06_03_select/src/lib.rs:example}}
```
@ -27,7 +27,7 @@ if none of the other futures are ready.
being `select`ed over have completed and will no longer make progress.
This is often handy when looping over a `select!`.
```rust
```rust,edition2018
{{#include ../../examples/06_03_select/src/lib.rs:default_and_complete}}
```
@ -58,7 +58,7 @@ which implement this trait or have been wrapped using `.fuse()`
will yield `FusedFuture` futures from their
`.next()` / `.try_next()` combinators.
```rust
```rust,edition2018
{{#include ../../examples/06_03_select/src/lib.rs:fused_stream}}
```
@ -75,7 +75,7 @@ Note the use of the `.select_next_some()` function. This can be
used with `select` to only run the branch for `Some(_)` values
returned from the stream, ignoring `None`s.
```rust
```rust,edition2018
{{#include ../../examples/06_03_select/src/lib.rs:fuse_terminated}}
```
@ -85,6 +85,6 @@ to the one above, but will run each copy of `run_on_new_num_fut`
to completion, rather than aborting them when a new one is created.
It will also print out a value returned by `run_on_new_num_fut`.
```rust
```rust,edition2018
{{#include ../../examples/06_03_select/src/lib.rs:futures_unordered}}
```

View File

@ -55,7 +55,7 @@ In practice, this means that returning `Box<dyn Trait>` objects from an
This code will result in an error:
```
```rust,edition2018,ignore
async fn x() -> Box<dyn std::fmt::Display> {
Box::new("foo")
}
@ -63,7 +63,7 @@ async fn x() -> Box<dyn std::fmt::Display> {
This issue can be worked around by manually casting using `as`:
```
```rust,edition2018
async fn x() -> Box<dyn std::fmt::Display> {
Box::new("foo") as Box<dyn std::fmt::Display>
}

View File

@ -7,7 +7,10 @@ This can cause the compiler to fail to infer the error type of the
For example, this code:
```rust
```rust,edition2018
# struct MyError;
# async fn foo() -> Result<(), MyError> { Ok(()) }
# async fn bar() -> Result<(), MyError> { Ok(()) }
let fut = async {
foo().await?;
bar().await?;
@ -32,7 +35,10 @@ to explicitly specify the return type of an `async` block.
To work around this, use the "turbofish" operator to supply the success and
error types for the `async` block:
```rust
```rust,edition2018
# struct MyError;
# async fn foo() -> Result<(), MyError> { Ok(()) }
# async fn bar() -> Result<(), MyError> { Ok(()) }
let fut = async {
foo().await?;
bar().await?;

View File

@ -19,7 +19,7 @@ struct NotSend(Rc<()>);
Variables of type `NotSend` can briefly appear as temporaries in `async fn`s
even when the resulting `Future` type returned by the `async fn` must be `Send`:
```rust
```rust,edition2018
# use std::rc::Rc;
# #[derive(Default)]
# struct NotSend(Rc<()>);
@ -39,14 +39,19 @@ fn main() {
However, if we change `foo` to store `NotSend` in a variable, this example no
longer compiles:
```rust
```rust,edition2018
# use std::rc::Rc;
# #[derive(Default)]
# struct NotSend(Rc<()>);
# async fn bar() {}
async fn foo() {
let x = NotSend::default();
bar().await;
}
# fn require_send(_: impl Send) {}
# fn main() {
# require_send(foo());
# }
```
```
@ -85,14 +90,19 @@ a block scope encapsulating any non-`Send` variables. This makes it easier
for the compiler to tell that these variables do not live across an
`.await` point.
```rust
```rust,edition2018
# use std::rc::Rc;
# #[derive(Default)]
# struct NotSend(Rc<()>);
# async fn bar() {}
async fn foo() {
{
let x = NotSend::default();
}
bar().await;
}
# fn require_send(_: impl Send) {}
# fn main() {
# require_send(foo());
# }
```

View File

@ -4,7 +4,11 @@ Internally, `async fn` creates a state machine type containing each
sub-`Future` being `.await`ed. This makes recursive `async fn`s a little
tricky, since the resulting state machine type has to contain itself:
```rust
```rust,edition2018
# async fn step_one() { /* ... */ }
# async fn step_two() { /* ... */ }
# struct StepOne;
# struct StepTwo;
// This function:
async fn foo() {
step_one().await;
@ -48,6 +52,6 @@ Unfortunately, compiler limitations mean that just wrapping the calls to
to make `recursive` into a non-`async` function which returns a `.boxed()`
`async` block:
```rust
```rust,edition2018
{{#include ../../examples/07_05_recursion/src/lib.rs:example}}
```