Merge branch 'rust-lang:master' into master

This commit is contained in:
Jia Chao 2022-07-06 14:45:26 +08:00 committed by GitHub
commit 4dc5f4ef9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 49 additions and 37 deletions

View File

@ -37,7 +37,7 @@ impl SimpleFuture for SocketRead<'_> {
fn poll(&mut self, wake: fn()) -> Poll<Self::Output> {
if self.socket.has_data_to_read() {
// The socket has data-- read it into a buffer and return it.
// The socket has data -- read it into a buffer and return it.
Poll::Ready(self.socket.read_buf())
} else {
// The socket does not yet have data.
@ -89,7 +89,7 @@ where
}
if self.a.is_none() && self.b.is_none() {
// Both futures have completed-- we can return successfully
// Both futures have completed -- we can return successfully
Poll::Ready(())
} else {
// One or both futures returned `Poll::Pending` and still have
@ -121,7 +121,7 @@ where
fn poll(&mut self, wake: fn()) -> Poll<Self::Output> {
if let Some(first) = &mut self.first {
match first.poll(wake) {
// We've completed the first future-- remove it and start on
// We've completed the first future -- remove it and start on
// the second!
Poll::Ready(()) => self.first.take(),
// We couldn't yet complete the first future.

View File

@ -10,7 +10,7 @@ use {
future::Future,
sync::mpsc::{sync_channel, Receiver, SyncSender},
sync::{Arc, Mutex},
task::{Context, Poll},
task::Context,
time::Duration,
},
// The timer we wrote in the previous section:
@ -97,7 +97,7 @@ impl Executor {
// `Pin<Box<dyn Future<Output = T> + Send + 'static>>`.
// We can get a `Pin<&mut dyn Future + Send + 'static>`
// from it by calling the `Pin::as_mut` method.
if let Poll::Pending = future.as_mut().poll(context) {
if future.as_mut().poll(context).is_pending() {
// We're not done processing the future, so put it
// back in its task to be run again in the future.
*future_slot = Some(future);

View File

@ -62,12 +62,12 @@ async fn blocks() {
let future_one = async {
// ...
println!("{}", my_string);
println!("{my_string}");
};
let future_two = async {
// ...
println!("{}", my_string);
println!("{my_string}");
};
// Run both futures to completion, printing "foo" twice:
@ -84,7 +84,7 @@ fn move_block() -> impl Future<Output = ()> {
let my_string = "foo".to_string();
async move {
// ...
println!("{}", my_string);
println!("{my_string}");
}
}
// ANCHOR_END: async_move_examples

View File

@ -112,7 +112,7 @@ async fn run_loop(
}
},
new_num = get_new_num_fut => {
// A new number has arrived-- start a new `run_on_new_num_fut`,
// A new number has arrived -- start a new `run_on_new_num_fut`,
// dropping the old one.
run_on_new_num_fut.set(run_on_new_num(new_num).fuse());
},
@ -165,7 +165,7 @@ async fn run_loop(
}
},
new_num = get_new_num_fut => {
// A new number has arrived-- start a new `run_on_new_num_fut`.
// A new number has arrived -- start a new `run_on_new_num_fut`.
run_on_new_num_futs.push(run_on_new_num(new_num));
},
// Run the `run_on_new_num_futs` and check if any have completed

View File

@ -33,7 +33,7 @@ fn handle_connection(mut stream: TcpStream) {
// Write response back to the stream,
// and flush the stream to ensure the response is sent back to the client
let response = format!("{}{}", status_line, contents);
stream.write(response.as_bytes()).unwrap();
let response = format!("{status_line}{contents}");
stream.write_all(response.as_bytes()).unwrap();
stream.flush().unwrap();
}

View File

@ -33,7 +33,7 @@ async fn handle_connection(mut stream: TcpStream) {
};
let contents = fs::read_to_string(filename).unwrap();
let response = format!("{}{}", status_line, contents);
let response = format!("{status_line}{contents}");
stream.write(response.as_bytes()).unwrap();
stream.flush().unwrap();
}

View File

@ -33,7 +33,7 @@ async fn handle_connection(mut stream: impl Read + Write + Unpin) {
("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html")
};
let contents = fs::read_to_string(filename).unwrap();
let response = format!("{}{}", status_line, contents);
let response = format!("{status_line}{contents}");
stream.write(response.as_bytes()).await.unwrap();
stream.flush().await.unwrap();
}
@ -75,11 +75,14 @@ mod tests {
buf: &[u8],
) -> Poll<Result<usize, Error>> {
self.write_data = Vec::from(buf);
return Poll::Ready(Ok(buf.len()));
Poll::Ready(Ok(buf.len()))
}
fn poll_flush(self: Pin<&mut Self>, _: &mut Context) -> Poll<Result<(), Error>> {
Poll::Ready(Ok(()))
}
fn poll_close(self: Pin<&mut Self>, _: &mut Context) -> Poll<Result<(), Error>> {
Poll::Ready(Ok(()))
}

View File

@ -23,7 +23,7 @@ For the sake of the example, we'll just spin up a new thread when the timer
is created, sleep for the required time, and then signal the timer future
when the time window has elapsed.
First, start a new project with `cargo new timer_future` and add the imports
First, start a new project with `cargo new --lib timer_future` and add the imports
we'll need to get started to `src/lib.rs`:
```rust

View File

@ -108,8 +108,6 @@ types in Rust.
For now our example will look like this:
```rust, ignore
use std::pin::Pin;
#[derive(Debug)]
struct Test {
a: String,
@ -158,7 +156,6 @@ fn main() {
println!("a: {}, b: {}", test2.a(), test2.b());
}
# use std::pin::Pin;
# #[derive(Debug)]
# struct Test {
# a: String,
@ -210,7 +207,6 @@ fn main() {
println!("a: {}, b: {}", test2.a(), test2.b());
}
# use std::pin::Pin;
# #[derive(Debug)]
# struct Test {
# a: String,
@ -275,7 +271,6 @@ fn main() {
println!("a: {}, b: {}", test2.a(), test2.b());
}
# use std::pin::Pin;
# #[derive(Debug)]
# struct Test {
# a: String,
@ -318,8 +313,9 @@ It's easy to get this to show undefined behavior and fail in other spectacular w
Let's see how pinning and the `Pin` type can help us solve this problem.
The `Pin` type wraps pointer types, guaranteeing that the values behind the
pointer won't be moved. For example, `Pin<&mut T>`, `Pin<&T>`,
`Pin<Box<T>>` all guarantee that `T` won't be moved even if `T: !Unpin`.
pointer won't be moved if it is not implementing `Unpin`. For example, `Pin<&mut
T>`, `Pin<&T>`, `Pin<Box<T>>` all guarantee that `T` won't be moved if `T:
!Unpin`.
Most types don't have a problem being moved. These types implement a trait
called `Unpin`. Pointers to `Unpin` types can be freely placed into or taken
@ -354,17 +350,18 @@ impl Test {
_marker: PhantomPinned, // This makes our type `!Unpin`
}
}
fn init<'a>(self: Pin<&'a mut Self>) {
fn init(self: Pin<&mut Self>) {
let self_ptr: *const String = &self.a;
let this = unsafe { self.get_unchecked_mut() };
this.b = self_ptr;
}
fn a<'a>(self: Pin<&'a Self>) -> &'a str {
fn a(self: Pin<&Self>) -> &str {
&self.get_ref().a
}
fn b<'a>(self: Pin<&'a Self>) -> &'a String {
fn b(self: Pin<&Self>) -> &String {
assert!(!self.b.is_null(), "Test::b called without Test::init being called first");
unsafe { &*(self.b) }
}
@ -412,17 +409,18 @@ pub fn main() {
# _marker: PhantomPinned,
# }
# }
# fn init<'a>(self: Pin<&'a mut Self>) {
#
# fn init(self: Pin<&mut Self>) {
# let self_ptr: *const String = &self.a;
# let this = unsafe { self.get_unchecked_mut() };
# this.b = self_ptr;
# }
#
# fn a<'a>(self: Pin<&'a Self>) -> &'a str {
# fn a(self: Pin<&Self>) -> &str {
# &self.get_ref().a
# }
#
# fn b<'a>(self: Pin<&'a Self>) -> &'a String {
# fn b(self: Pin<&Self>) -> &String {
# assert!(!self.b.is_null(), "Test::b called without Test::init being called first");
# unsafe { &*(self.b) }
# }
@ -464,17 +462,18 @@ pub fn main() {
# _marker: PhantomPinned, // This makes our type `!Unpin`
# }
# }
# fn init<'a>(self: Pin<&'a mut Self>) {
#
# fn init(self: Pin<&mut Self>) {
# let self_ptr: *const String = &self.a;
# let this = unsafe { self.get_unchecked_mut() };
# this.b = self_ptr;
# }
#
# fn a<'a>(self: Pin<&'a Self>) -> &'a str {
# fn a(self: Pin<&Self>) -> &str {
# &self.get_ref().a
# }
#
# fn b<'a>(self: Pin<&'a Self>) -> &'a String {
# fn b(self: Pin<&Self>) -> &String {
# assert!(!self.b.is_null(), "Test::b called without Test::init being called first");
# unsafe { &*(self.b) }
# }
@ -498,8 +497,10 @@ The type system prevents us from moving the data.
> let mut test1 = Test::new("test1");
> let mut test1_pin = unsafe { Pin::new_unchecked(&mut test1) };
> Test::init(test1_pin.as_mut());
>
> drop(test1_pin);
> println!(r#"test1.b points to "test1": {:?}..."#, test1.b);
>
> let mut test2 = Test::new("test2");
> mem::swap(&mut test1, &mut test2);
> println!("... and now it points nowhere: {:?}", test1.b);
@ -525,6 +526,7 @@ The type system prevents us from moving the data.
> # _marker: PhantomPinned,
> # }
> # }
> #
> # fn init<'a>(self: Pin<&'a mut Self>) {
> # let self_ptr: *const String = &self.a;
> # let this = unsafe { self.get_unchecked_mut() };
@ -567,24 +569,24 @@ impl Test {
_marker: PhantomPinned,
};
let mut boxed = Box::pin(t);
let self_ptr: *const String = &boxed.as_ref().a;
let self_ptr: *const String = &boxed.a;
unsafe { boxed.as_mut().get_unchecked_mut().b = self_ptr };
boxed
}
fn a<'a>(self: Pin<&'a Self>) -> &'a str {
fn a(self: Pin<&Self>) -> &str {
&self.get_ref().a
}
fn b<'a>(self: Pin<&'a Self>) -> &'a String {
fn b(self: Pin<&Self>) -> &String {
unsafe { &*(self.b) }
}
}
pub fn main() {
let mut test1 = Test::new("test1");
let mut test2 = Test::new("test2");
let test1 = Test::new("test1");
let test2 = Test::new("test2");
println!("a: {}, b: {}",test1.as_ref().a(), test1.as_ref().b());
println!("a: {}, b: {}",test2.as_ref().a(), test2.as_ref().b());

View File

@ -0,0 +1,6 @@
# Appendix : Translations of the Book
For resources in languages other than English.
- [Русский](https://doc.rust-lang.ru/async-book/)
- [Français](https://jimskapt.github.io/async-book-fr/)

View File

@ -34,3 +34,4 @@
- [TODO: Asynchronous Design Patterns: Solutions and Suggestions]()
- [TODO: Modeling Servers and the Request/Response Pattern]()
- [TODO: Managing Shared State]()
- [Appendix: Translations of the Book](12_appendix/01_translations.md)