Skip to content

Commit

Permalink
Merge main into async-chapter
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskrycho committed Oct 7, 2024
2 parents c1d60d0 + f38ce8b commit 78881f6
Show file tree
Hide file tree
Showing 22 changed files with 528 additions and 336 deletions.
2 changes: 0 additions & 2 deletions ci/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ personal_ws-1.1 en 0 utf-8
abcabcabc
abcd
abcdefghijklmnopqrstuvwxyz
adaptor
adaptors
AddAssign
Addr
adfb
Expand Down
68 changes: 37 additions & 31 deletions dot/trpl04-05.dot
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
digraph {
rankdir=LR;
overlap=false;
dpi=300.0;
node [shape="plaintext"];

table0[label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD COLSPAN="2" SIDES="B">s</TD></TR>
<TR><TD>name</TD><TD>value</TD></TR>
<TR><TD>ptr</TD><TD PORT="borrower"></TD></TR>
</TABLE>>];
table1[label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD COLSPAN="2" SIDES="B">s1</TD></TR>
<TR><TD>name</TD><TD>value</TD></TR>
<TR><TD PORT="borrowee">ptr</TD><TD PORT="pointer"></TD></TR>
<TR><TD>len</TD><TD>5</TD></TR>
<TR><TD>capacity</TD><TD>5</TD></TR>
</TABLE>>];
table2[label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD>index</TD><TD>value</TD></TR>
<TR><TD PORT="pointee">0</TD><TD>h</TD></TR>
<TR><TD>1</TD><TD>e</TD></TR>
<TR><TD>2</TD><TD>l</TD></TR>
<TR><TD>3</TD><TD>l</TD></TR>
<TR><TD>4</TD><TD>o</TD></TR>
</TABLE>>];

edge[tailclip="false"];
table1:pointer:c -> table2:pointee;
table0:borrower:c -> table1:borrowee;
}

rankdir = LR;
overlap = false;
dpi = 300.0;
node [shape = "plaintext";];

s [label = <<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD COLSPAN="2" SIDES="B">s</TD></TR>
<TR><TD>name</TD><TD>value</TD></TR>
<TR><TD>ptr</TD><TD PORT="pointer"></TD></TR>
<TR><TD>len</TD><TD>4</TD></TR>
<TR><TD>capacity</TD><TD>4</TD></TR>
</TABLE>>;];

subgraph cluster_heap {
peripheries = 0;
rank = "same";

hello [label = <<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD>index</TD><TD>value</TD></TR>
<TR><TD PORT="pointee">0</TD><TD>h</TD></TR>
<TR><TD>1</TD><TD>e</TD></TR>
<TR><TD>2</TD><TD>l</TD></TR>
<TR><TD>3</TD><TD>l</TD></TR>
<TR><TD>4</TD><TD>o</TD></TR>
</TABLE>>;];

ahoy [label = <<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD>index</TD><TD>value</TD></TR>
<TR><TD PORT="pointee">0</TD><TD>a</TD></TR>
<TR><TD>1</TD><TD>h</TD></TR>
<TR><TD>2</TD><TD>o</TD></TR>
<TR><TD>3</TD><TD>y</TD></TR>
</TABLE>>;];
}

s -> ahoy [tailport = "pointer:c"; headport = "pointee"; tailclip = false;];
}
29 changes: 10 additions & 19 deletions dot/trpl04-06.dot
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,28 @@ digraph {
node [shape="plaintext"];

table0[label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD COLSPAN="2" SIDES="B">world</TD></TR>
<TR><TD COLSPAN="2" SIDES="B">s</TD></TR>
<TR><TD>name</TD><TD>value</TD></TR>
<TR><TD>ptr</TD><TD PORT="pointer2"></TD></TR>
<TR><TD>len</TD><TD>5</TD></TR>
<TR><TD>ptr</TD><TD PORT="borrower"></TD></TR>
</TABLE>>];

table3[label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD COLSPAN="2" SIDES="B">s</TD></TR>
table1[label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD COLSPAN="2" SIDES="B">s1</TD></TR>
<TR><TD>name</TD><TD>value</TD></TR>
<TR><TD>ptr</TD><TD PORT="pointer"></TD></TR>
<TR><TD>len</TD><TD>11</TD></TR>
<TR><TD>capacity</TD><TD>11</TD></TR>
<TR><TD PORT="borrowee">ptr</TD><TD PORT="pointer"></TD></TR>
<TR><TD>len</TD><TD>5</TD></TR>
<TR><TD>capacity</TD><TD>5</TD></TR>
</TABLE>>];
table4[label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
table2[label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD>index</TD><TD>value</TD></TR>
<TR><TD PORT="pointee">0</TD><TD>h</TD></TR>
<TR><TD>1</TD><TD>e</TD></TR>
<TR><TD>2</TD><TD>l</TD></TR>
<TR><TD>3</TD><TD>l</TD></TR>
<TR><TD>4</TD><TD>o</TD></TR>
<TR><TD>5</TD><TD> </TD></TR>
<TR><TD PORT="pointee2">6</TD><TD>w</TD></TR>
<TR><TD>7</TD><TD>o</TD></TR>
<TR><TD>8</TD><TD>r</TD></TR>
<TR><TD>9</TD><TD>l</TD></TR>
<TR><TD>10</TD><TD>d</TD></TR>
</TABLE>>];


edge[tailclip="false"];
table0:pointer2:c -> table4:pointee2;
table3:pointer:c -> table4:pointee;
table1:pointer:c -> table2:pointee;
table0:borrower:c -> table1:borrowee;
}

41 changes: 41 additions & 0 deletions dot/trpl04-07.dot
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
digraph {
rankdir=LR;
overlap=false;
dpi=300.0;
node [shape="plaintext"];

table0[label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD COLSPAN="2" SIDES="B">world</TD></TR>
<TR><TD>name</TD><TD>value</TD></TR>
<TR><TD>ptr</TD><TD PORT="pointer2"></TD></TR>
<TR><TD>len</TD><TD>5</TD></TR>
</TABLE>>];

table3[label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD COLSPAN="2" SIDES="B">s</TD></TR>
<TR><TD>name</TD><TD>value</TD></TR>
<TR><TD>ptr</TD><TD PORT="pointer"></TD></TR>
<TR><TD>len</TD><TD>11</TD></TR>
<TR><TD>capacity</TD><TD>11</TD></TR>
</TABLE>>];
table4[label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD>index</TD><TD>value</TD></TR>
<TR><TD PORT="pointee">0</TD><TD>h</TD></TR>
<TR><TD>1</TD><TD>e</TD></TR>
<TR><TD>2</TD><TD>l</TD></TR>
<TR><TD>3</TD><TD>l</TD></TR>
<TR><TD>4</TD><TD>o</TD></TR>
<TR><TD>5</TD><TD> </TD></TR>
<TR><TD PORT="pointee2">6</TD><TD>w</TD></TR>
<TR><TD>7</TD><TD>o</TD></TR>
<TR><TD>8</TD><TD>r</TD></TR>
<TR><TD>9</TD><TD>l</TD></TR>
<TR><TD>10</TD><TD>d</TD></TR>
</TABLE>>];


edge[tailclip="false"];
table0:pointer2:c -> table4:pointee2;
table3:pointer:c -> table4:pointee;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "ownership"
version = "0.1.0"
edition = "2021"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fn main() {
// ANCHOR: here
let mut s = String::from("hello");
s = String::from("ahoy");

println!("{s}, world!");
// ANCHOR_END: here
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ failures:
I got the value 8
thread 'tests::this_test_will_fail' panicked at src/lib.rs:19:9:
assertion `left == right` failed
left: 5
right: 10
left: 10
right: 5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ mod tests {
#[test]
fn this_test_will_pass() {
let value = prints_and_returns_10(4);
assert_eq!(10, value);
assert_eq!(value, 10);
}

#[test]
fn this_test_will_fail() {
let value = prints_and_returns_10(8);
assert_eq!(5, value);
assert_eq!(value, 5);
}
}
16 changes: 8 additions & 8 deletions src/ch03-02-data-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,14 +271,14 @@ brackets:
{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-13-arrays/src/main.rs}}
```

Arrays are useful when you want your data allocated on the stack rather than
the heap (we will discuss the stack and the heap more in [Chapter
4][stack-and-heap]<!-- ignore -->) or when you want to ensure you always have a
fixed number of elements. An array isn’t as flexible as the vector type,
though. A *vector* is a similar collection type provided by the standard
library that *is* allowed to grow or shrink in size. If you’re unsure whether
to use an array or a vector, chances are you should use a vector. [Chapter
8][vectors]<!-- ignore --> discusses vectors in more detail.
Arrays are useful when you want your data allocated on the stack, the same as
the other types we have seen so far, rather than the heap (we will discuss the
stack and the heap more in [Chapter 4][stack-and-heap]<!-- ignore -->) or when
you want to ensure you always have a fixed number of elements. An array isn’t as
flexible as the vector type, though. A *vector* is a similar collection type
provided by the standard library that *is* allowed to grow or shrink in size. If
you’re unsure whether to use an array or a vector, chances are you should use a
vector. [Chapter 8][vectors]<!-- ignore --> discusses vectors in more detail.

However, arrays are more useful when you know the number of elements will not
need to change. For example, if you were using the names of the month in a
Expand Down
55 changes: 43 additions & 12 deletions src/ch04-01-what-is-ownership.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,13 @@ hardcoded into the text of our program. The variable is valid from the point at
which it’s declared until the end of the current *scope*. Listing 4-1 shows a
program with comments annotating where the variable `s` would be valid.

<Listing number="4-1" caption="A variable and the scope in which it is valid">

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-01/src/main.rs:here}}
```

<span class="caption">Listing 4-1: A variable and the scope in which it is
valid</span>
</Listing>

In other words, there are two important points in time here:

Expand Down Expand Up @@ -239,12 +240,13 @@ we’ve allocated on the heap. Let’s explore some of those situations now.
Multiple variables can interact with the same data in different ways in Rust.
Let’s look at an example using an integer in Listing 4-2.

<Listing number="4-2" caption="Assigning the integer value of variable `x` to `y`">

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-02/src/main.rs:here}}
```

<span class="caption">Listing 4-2: Assigning the integer value of variable `x`
to `y`</span>
</Listing>

We can probably guess what this is doing: “bind the value `5` to `x`; then make
a copy of the value in `x` and bind it to `y`.” We now have two variables, `x`
Expand Down Expand Up @@ -354,6 +356,37 @@ In addition, there’s a design choice that’s implied by this: Rust will never
automatically create “deep” copies of your data. Therefore, any *automatic*
copying can be assumed to be inexpensive in terms of runtime performance.

#### Scope and Assignment

The inverse of this is true for the relationship between scoping, ownership, and
memory being freed via the `drop` function as well. When you assign a completely
new value to an existing variable, Rust will call `drop` and free the original
value’s memory immediately. Consider this code, for example:

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-04b-replacement-drop/src/main.rs:here}}
```

We initially declare a variable `s` and bind it to a `String` with the value
`"hello"`. Then we immediately create a new `String` with the value `"ahoy"` and
assign it to `s`. At this point, nothing is referring to the original value on
the heap at all.

<img alt="One table s representing the string value on the stack, pointing to
the second piece of string data (ahoy) on the heap, with the original string
data (hello) grayed out because it cannot be accessed anymore."
src="img/trpl04-05.svg"
class="center"
style="width: 50%;"
/>

<span class="caption">Figure 4-5: Representation in memory after the initial
value has been replaced in its entirety.</span>

The original string thus immediately goes out of scope. Rust will run the `drop`
function on it and its memory will be freed right away. When we print the value
at the end, it will be `"ahoy, world!"`.

<!-- Old heading. Do not remove or links may break. -->
<a id="ways-variables-and-data-interact-clone"></a>

Expand Down Expand Up @@ -429,14 +462,13 @@ assigning a value to a variable. Passing a variable to a function will move or
copy, just as assignment does. Listing 4-3 has an example with some annotations
showing where variables go into and out of scope.

<span class="filename">Filename: src/main.rs</span>
<Listing number="4-3" file-name="src/main.rs" caption="Functions with ownership and scope annotated">

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-03/src/main.rs}}
```

<span class="caption">Listing 4-3: Functions with ownership and scope
annotated</span>
</Listing>

If we tried to use `s` after the call to `takes_ownership`, Rust would throw a
compile-time error. These static checks protect us from mistakes. Try adding
Expand All @@ -449,14 +481,13 @@ Returning values can also transfer ownership. Listing 4-4 shows an example of a
function that returns some value, with similar annotations as those in Listing
4-3.

<span class="filename">Filename: src/main.rs</span>
<Listing number="4-4" file-name="src/main.rs" caption="Transferring ownership of return values">

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-04/src/main.rs}}
```

<span class="caption">Listing 4-4: Transferring ownership of return
values</span>
</Listing>

The ownership of a variable follows the same pattern every time: assigning a
value to another variable moves it. When a variable that includes data on the
Expand All @@ -471,13 +502,13 @@ from the body of the function that we might want to return as well.

Rust does let us return multiple values using a tuple, as shown in Listing 4-5.

<span class="filename">Filename: src/main.rs</span>
<Listing number="4-5" file-name="src/main.rs" caption="Returning ownership of parameters">

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-05/src/main.rs}}
```

<span class="caption">Listing 4-5: Returning ownership of parameters</span>
</Listing>

But this is too much ceremony and a lot of work for a concept that should be
common. Luckily for us, Rust has a feature for using a value without
Expand Down
Loading

0 comments on commit 78881f6

Please sign in to comment.