Adopt <Listing> for Ch. 20

This commit is contained in:
Chris Krycho
2024-10-09 09:28:11 -06:00
parent 7335c65357
commit bfcebbb2ca
5 changed files with 95 additions and 92 deletions

View File

@@ -91,11 +91,13 @@ interface with another language or hardware where Rusts guarantees dont ap
Listing 20-1 shows how to create an immutable and a mutable raw pointer from
references.
<Listing number="20-1" caption="Creating raw pointers from references">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-01/src/main.rs:here}}
```
<span class="caption">Listing 20-1: Creating raw pointers from references</span>
</Listing>
Notice that we dont include the `unsafe` keyword in this code. We can create
raw pointers in safe code; we just cant dereference raw pointers outside an
@@ -115,23 +117,25 @@ so there is no memory access, or the program might error with a segmentation
fault. Usually, there is no good reason to write code like this, but it is
possible.
<Listing number="20-2" caption="Creating a raw pointer to an arbitrary memory address">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-02/src/main.rs:here}}
```
<span class="caption">Listing 20-2: Creating a raw pointer to an arbitrary
memory address</span>
</Listing>
Recall that we can create raw pointers in safe code, but we cant *dereference*
raw pointers and read the data being pointed to. In Listing 20-3, we use the
dereference operator `*` on a raw pointer that requires an `unsafe` block.
<Listing number="20-3" caption="Dereferencing raw pointers within an `unsafe` block">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-03/src/main.rs:here}}
```
<span class="caption">Listing 20-3: Dereferencing raw pointers within an
`unsafe` block</span>
</Listing>
Creating a pointer does no harm; its only when we try to access the value that
it points at that we might end up dealing with an invalid value.
@@ -196,24 +200,26 @@ we might implement it. This safe method is defined on mutable slices: it takes
one slice and makes it two by splitting the slice at the index given as an
argument. Listing 20-4 shows how to use `split_at_mut`.
<Listing number="20-4" caption="Using the safe `split_at_mut` function">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-04/src/main.rs:here}}
```
<span class="caption">Listing 20-4: Using the safe `split_at_mut`
function</span>
</Listing>
We cant implement this function using only safe Rust. An attempt might look
something like Listing 20-5, which wont compile. For simplicity, well
implement `split_at_mut` as a function rather than a method and only for slices
of `i32` values rather than for a generic type `T`.
<Listing number="20-5" caption="An attempted implementation of `split_at_mut` using only safe Rust">
```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-05/src/main.rs:here}}
```
<span class="caption">Listing 20-5: An attempted implementation of
`split_at_mut` using only safe Rust</span>
</Listing>
This function first gets the total length of the slice. Then it asserts that
the index given as a parameter is within the slice by checking whether its
@@ -240,12 +246,13 @@ know code is okay, but Rust doesnt, its time to reach for unsafe code.
Listing 20-6 shows how to use an `unsafe` block, a raw pointer, and some calls
to unsafe functions to make the implementation of `split_at_mut` work.
<Listing number="20-6" caption="Using unsafe code in the implementation of the `split_at_mut` function">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-06/src/main.rs:here}}
```
<span class="caption">Listing 20-6: Using unsafe code in the implementation of
the `split_at_mut` function</span>
</Listing>
Recall from [“The Slice Type”][the-slice-type]<!-- ignore --> section in
Chapter 4 that slices are a pointer to some data and the length of the slice.
@@ -282,12 +289,13 @@ In contrast, the use of `slice::from_raw_parts_mut` in Listing 20-7 would
likely crash when the slice is used. This code takes an arbitrary memory
location and creates a slice 10,000 items long.
<Listing number="20-7" caption="Creating a slice from an arbitrary memory location">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-07/src/main.rs:here}}
```
<span class="caption">Listing 20-7: Creating a slice from an arbitrary memory
location</span>
</Listing>
We dont own the memory at this arbitrary location, and there is no guarantee
that the slice this code creates contains valid `i32` values. Attempting to use
@@ -307,14 +315,13 @@ always unsafe to call from Rust code. The reason is that other languages dont
enforce Rusts rules and guarantees, and Rust cant check them, so
responsibility falls on the programmer to ensure safety.
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-8" file-name="src/main.rs" caption="Declaring and calling an `extern` function defined in another language">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-08/src/main.rs}}
```
<span class="caption">Listing 20-8: Declaring and calling an `extern` function
defined in another language</span>
</Listing>
Within the `extern "C"` block, we list the names and signatures of external
functions from another language we want to call. The `"C"` part defines which
@@ -357,14 +364,13 @@ In Rust, global variables are called *static* variables. Listing 20-9 shows an
example declaration and use of a static variable with a string slice as a
value.
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-9" file-name="src/main.rs" caption="Defining and using an immutable static variable">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-09/src/main.rs}}
```
<span class="caption">Listing 20-9: Defining and using an immutable static
variable</span>
</Listing>
Static variables are similar to constants, which we discussed in the
[“Differences Between Variables and
@@ -383,14 +389,13 @@ variables can be mutable. Accessing and modifying mutable static variables is
*unsafe*. Listing 20-10 shows how to declare, access, and modify a mutable
static variable named `COUNTER`.
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-10" file-name="src/main.rs" caption="Reading from or writing to a mutable static variable is unsafe">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-10/src/main.rs}}
```
<span class="caption">Listing 20-10: Reading from or writing to a mutable
static variable is unsafe</span>
</Listing>
As with regular variables, we specify mutability using the `mut` keyword. Any
code that reads or writes from `COUNTER` must be within an `unsafe` block. This
@@ -412,12 +417,13 @@ declare that a trait is `unsafe` by adding the `unsafe` keyword before `trait`
and marking the implementation of the trait as `unsafe` too, as shown in
Listing 20-11.
<Listing number="20-11" caption="Defining and implementing an unsafe trait">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-11/src/main.rs}}
```
<span class="caption">Listing 20-11: Defining and implementing an unsafe
trait</span>
</Listing>
By using `unsafe impl`, were promising that well uphold the invariants that
the compiler cant verify.

View File

@@ -25,12 +25,13 @@ for the type of the values the type implementing the `Iterator` trait is
iterating over. The definition of the `Iterator` trait is as shown in Listing
20-12.
<Listing number="20-12" caption="The definition of the `Iterator` trait that has an associated type `Item`">
```rust,noplayground
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-12/src/lib.rs}}
```
<span class="caption">Listing 20-12: The definition of the `Iterator` trait
that has an associated type `Item`</span>
</Listing>
The type `Item` is a placeholder, and the `next` methods definition shows that
it will return values of type `Option<Self::Item>`. Implementors of the
@@ -43,21 +44,24 @@ handle. To examine the difference between the two concepts, well look at an
implementation of the `Iterator` trait on a type named `Counter` that specifies
the `Item` type is `u32`:
<span class="filename">Filename: src/lib.rs</span>
<Listing file-name="src/lib.rs">
```rust,ignore
{{#rustdoc_include ../listings/ch20-advanced-features/no-listing-22-iterator-on-counter/src/lib.rs:ch19}}
```
</Listing>
This syntax seems comparable to that of generics. So why not just define the
`Iterator` trait with generics, as shown in Listing 20-13?
<Listing number="20-13" number="A hypothetical definition of the `Iterator` trait using generics">
```rust,noplayground
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-13/src/lib.rs}}
```
<span class="caption">Listing 20-13: A hypothetical definition of the
`Iterator` trait using generics</span>
</Listing>
The difference is that when using generics, as in Listing 20-13, we must
annotate the types in each implementation; because we can also implement
@@ -98,14 +102,13 @@ example, in Listing 20-14 we overload the `+` operator to add two `Point`
instances together. We do this by implementing the `Add` trait on a `Point`
struct:
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-14" file-name="src/main.rs" caption="Implementing the `Add` trait to overload the `+` operator for `Point` instances">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-14/src/main.rs}}
```
<span class="caption">Listing 20-14: Implementing the `Add` trait to overload
the `+` operator for `Point` instances</span>
</Listing>
The `add` method adds the `x` values of two `Point` instances and the `y`
values of two `Point` instances to create a new `Point`. The `Add` trait has an
@@ -144,14 +147,13 @@ Pattern to Implement External Traits on External Types”][newtype]<!-- ignore
the implementation of `Add` do the conversion correctly. We can implement `Add`
for `Millimeters` with `Meters` as the `Rhs`, as shown in Listing 20-15.
<span class="filename">Filename: src/lib.rs</span>
<Listing number="20-15" file-name="src/lib.rs" caption="Implementing the `Add` trait on `Millimeters` to add `Millimeters` to `Meters`">
```rust,noplayground
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-15/src/lib.rs}}
```
<span class="caption">Listing 20-15: Implementing the `Add` trait on
`Millimeters` to add `Millimeters` to `Meters`</span>
</Listing>
To add `Millimeters` and `Meters`, we specify `impl Add<Meters>` to set the
value of the `Rhs` type parameter instead of using the default of `Self`.
@@ -186,27 +188,24 @@ want to use. Consider the code in Listing 20-16 where weve defined two traits
both traits on a type `Human` that already has a method named `fly` implemented
on it. Each `fly` method does something different.
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-16" file-name="src/main.rs" caption="Two traits are defined to have a ` method and are implemented on the `Human` type, and a `fly` method is implemented on `Human` directly">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-16/src/main.rs:here}}
```
<span class="caption">Listing 20-16: Two traits are defined to have a `fly`
method and are implemented on the `Human` type, and a `fly` method is
implemented on `Human` directly</span>
</Listing>
When we call `fly` on an instance of `Human`, the compiler defaults to calling
the method that is directly implemented on the type, as shown in Listing 20-17.
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-17" file-name="src/main.rs" caption="Calling `fly` on an instance of `Human`">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-17/src/main.rs:here}}
```
<span class="caption">Listing 20-17: Calling `fly` on an instance of
`Human`</span>
</Listing>
Running this code will print `*waving arms furiously*`, showing that Rust
called the `fly` method implemented on `Human` directly.
@@ -215,14 +214,13 @@ To call the `fly` methods from either the `Pilot` trait or the `Wizard` trait,
we need to use more explicit syntax to specify which `fly` method we mean.
Listing 20-18 demonstrates this syntax.
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-18" file-name="src/main.rs" caption="Specifying which traits `fly` method we want to call">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-18/src/main.rs:here}}
```
<span class="caption">Listing 20-18: Specifying which traits `fly` method we
want to call</span>
</Listing>
Specifying the trait name before the method name clarifies to Rust which
implementation of `fly` we want to call. We could also write
@@ -249,15 +247,13 @@ We make an `Animal` trait with an associated non-method function `baby_name`.
The `Animal` trait is implemented for the struct `Dog`, on which we also
provide an associated non-method function `baby_name` directly.
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-19" file-name="src/main.rs" caption="A trait with an associated function and a type with an associated function of the same name that also implements the trait">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-19/src/main.rs}}
```
<span class="caption">Listing 20-19: A trait with an associated function and a
type with an associated function of the same name that also implements the
trait</span>
</Listing>
We implement the code for naming all puppies Spot in the `baby_name` associated
function that is defined on `Dog`. The `Dog` type also implements the trait
@@ -278,15 +274,13 @@ is part of the `Animal` trait that we implemented on `Dog` so the code prints
we used in Listing 20-18 doesnt help here; if we change `main` to the code in
Listing 20-20, well get a compilation error.
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-20" file-name="src/main.rs" caption="Attempting to call the `baby_name` function from the `Animal` trait, but Rust doesnt know which implementation to use">
```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-20/src/main.rs:here}}
```
<span class="caption">Listing 20-20: Attempting to call the `baby_name`
function from the `Animal` trait, but Rust doesnt know which implementation to
use</span>
</Listing>
Because `Animal::baby_name` doesnt have a `self` parameter, and there could be
other types that implement the `Animal` trait, Rust cant figure out which
@@ -301,15 +295,13 @@ To disambiguate and tell Rust that we want to use the implementation of
type, we need to use fully qualified syntax. Listing 20-21 demonstrates how to
use fully qualified syntax.
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-21" file-name="src/main.rs" caption="Using fully qualified syntax to specify that we want to call the `baby_name` function from the `Animal` trait as implemented on `Dog`">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-21/src/main.rs:here}}
```
<span class="caption">Listing 20-21: Using fully qualified syntax to specify
that we want to call the `baby_name` function from the `Animal` trait as
implemented on `Dog`</span>
</Listing>
Were providing Rust with a type annotation within the angle brackets, which
indicates we want to call the `baby_name` method from the `Animal` trait as
@@ -365,14 +357,13 @@ trait definition by specifying `OutlinePrint: Display`. This technique is
similar to adding a trait bound to the trait. Listing 20-22 shows an
implementation of the `OutlinePrint` trait.
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-22" file-name="src/main.rs" caption="Implementing the `OutlinePrint` trait that requires the functionality from `Display`">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-22/src/main.rs:here}}
```
<span class="caption">Listing 20-22: Implementing the `OutlinePrint` trait that
requires the functionality from `Display`</span>
</Listing>
Because weve specified that `OutlinePrint` requires the `Display` trait, we
can use the `to_string` function that is automatically implemented for any type
@@ -384,12 +375,14 @@ the current scope.
Lets see what happens when we try to implement `OutlinePrint` on a type that
doesnt implement `Display`, such as the `Point` struct:
<span class="filename">Filename: src/main.rs</span>
<Listing file-name="src/main.rs">
```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch20-advanced-features/no-listing-02-impl-outlineprint-for-point/src/main.rs:here}}
```
</Listing>
We get an error saying that `Display` is required but not implemented:
```console
@@ -399,12 +392,14 @@ We get an error saying that `Display` is required but not implemented:
To fix this, we implement `Display` on `Point` and satisfy the constraint that
`OutlinePrint` requires, like so:
<span class="filename">Filename: src/main.rs</span>
<Listing file-name="src/main.rs">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/no-listing-03-impl-display-for-point/src/main.rs:here}}
```
</Listing>
Then implementing the `OutlinePrint` trait on `Point` will compile
successfully, and we can call `outline_print` on a `Point` instance to display
it within an outline of asterisks.
@@ -431,14 +426,13 @@ orphan rule prevents us from doing directly because the `Display` trait and the
that holds an instance of `Vec<T>`; then we can implement `Display` on
`Wrapper` and use the `Vec<T>` value, as shown in Listing 20-23.
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-23" file-name="src/main.rs" caption="Creating a `Wrapper` type around `Vec<String>` to implement `Display`">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-23/src/main.rs}}
```
<span class="caption">Listing 20-23: Creating a `Wrapper` type around
`Vec<String>` to implement `Display`</span>
</Listing>
The implementation of `Display` uses `self.0` to access the inner `Vec<T>`,
because `Wrapper` is a tuple struct and `Vec<T>` is the item at index 0 in the

View File

@@ -73,22 +73,25 @@ Writing this lengthy type in function signatures and as type annotations all
over the code can be tiresome and error prone. Imagine having a project full of
code like that in Listing 20-24.
<Listing number="20-24" caption="Using a long type in many places">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-24/src/main.rs:here}}
```
<span class="caption">Listing 20-24: Using a long type in many places</span>
</Listing>
A type alias makes this code more manageable by reducing the repetition. In
Listing 20-25, weve introduced an alias named `Thunk` for the verbose type and
can replace all uses of the type with the shorter alias `Thunk`.
<Listing number="20-25" caption="Introducing a type alias `Thunk` to reduce repetition">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-25/src/main.rs:here}}
```
<span class="caption">Listing 20-25: Introducing a type alias `Thunk` to reduce
repetition</span>
</Listing>
This code is much easier to read and write! Choosing a meaningful name for a
type alias can help communicate your intent as well (*thunk* is a word for code
@@ -147,12 +150,13 @@ But what use is a type you can never create values for? Recall the code from
Listing 2-5, part of the number guessing game; weve reproduced a bit of it
here in Listing 20-26.
<Listing number="20-26" caption="A `match` with an arm that ends in `continue`">
```rust,ignore
{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs:ch19}}
```
<span class="caption">Listing 20-26: A `match` with an arm that ends in
`continue`</span>
</Listing>
At the time, we skipped over some details in this code. In Chapter 6 in [“The
`match` Control Flow Operator”][the-match-control-flow-operator]<!-- ignore -->

View File

@@ -22,14 +22,13 @@ function `f` twice, passing it the `arg` value, then adds the two function call
results together. The `main` function calls `do_twice` with the arguments
`add_one` and `5`.
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-27" file-name="src/main.rs" caption="Using the `fn` type to accept a function pointer as an argument">
```rust
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-27/src/main.rs}}
```
<span class="caption">Listing 20-27: Using the `fn` type to accept a function
pointer as an argument</span>
</Listing>
This code prints `The answer is: 12`. We specify that the parameter `f` in
`do_twice` is an `fn` that takes one parameter of type `i32` and returns an

View File

@@ -75,14 +75,13 @@ because we wouldnt know the number or type of values up front.
Listing 20-28 shows a slightly simplified definition of the `vec!` macro.
<span class="filename">Filename: src/lib.rs</span>
<Listing number="20-28" file-name="src/lib.rs" caption="A simplified version of the `vec!` macro definition">
```rust,noplayground
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-28/src/lib.rs}}
```
<span class="caption">Listing 20-28: A simplified version of the `vec!` macro
definition</span>
</Listing>
> Note: The actual definition of the `vec!` macro in the standard library
> includes code to preallocate the correct amount of memory up front. That code
@@ -164,7 +163,7 @@ to eliminate in the future. In Listing 20-29, we show how to define a
procedural macro, where `some_attribute` is a placeholder for using a specific
macro variety.
<span class="filename">Filename: src/lib.rs</span>
<Listing number="20-29" file-name="src/lib.rs" caption="An example of defining a procedural macro">
```rust,ignore
use proc_macro;
@@ -174,8 +173,7 @@ pub fn some_name(input: TokenStream) -> TokenStream {
}
```
<span class="caption">Listing 20-29: An example of defining a procedural
macro</span>
</Listing>
The function that defines a procedural macro takes a `TokenStream` as an input
and produces a `TokenStream` as an output. The `TokenStream` type is defined by
@@ -202,14 +200,13 @@ TypeName!` where `TypeName` is the name of the type on which this trait has
been defined. In other words, well write a crate that enables another
programmer to write code like Listing 20-30 using our crate.
<span class="filename">Filename: src/main.rs</span>
<Listing number="20-30" file-name="src/main.rs" caption="The code a user of our crate will be able to write when using our procedural macro">
```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-30/src/main.rs}}
```
<span class="caption">Listing 20-30: The code a user of our crate will be able
to write when using our procedural macro</span>
</Listing>
This code will print `Hello, Macro! My name is Pancakes!` when were done. The
first step is to make a new library crate, like this:
@@ -220,12 +217,14 @@ $ cargo new hello_macro --lib
Next, well define the `HelloMacro` trait and its associated function:
<span class="filename">Filename: src/lib.rs</span>
<Listing file-name="src/lib.rs">
```rust,noplayground
{{#rustdoc_include ../listings/ch20-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/src/lib.rs}}
```
</Listing>
We have a trait and its function. At this point, our crate user could implement
the trait to achieve the desired functionality, like so:
@@ -269,24 +268,25 @@ Well also need functionality from the `syn` and `quote` crates, as youll s
in a moment, so we need to add them as dependencies. Add the following to the
*Cargo.toml* file for `hello_macro_derive`:
<span class="filename">Filename: hello_macro_derive/Cargo.toml</span>
<Listing file-name="hello_macro_derive/Cargo.toml">
```toml
{{#include ../listings/ch20-advanced-features/listing-20-31/hello_macro/hello_macro_derive/Cargo.toml:6:12}}
```
</Listing>
To start defining the procedural macro, place the code in Listing 20-31 into
your *src/lib.rs* file for the `hello_macro_derive` crate. Note that this code
wont compile until we add a definition for the `impl_hello_macro` function.
<span class="filename">Filename: hello_macro_derive/src/lib.rs</span>
<Listing number="20-31" file-name="hello_macro_derive/src/lib.rs" caption="Code that most procedural macro crates will require in order to process Rust code">
```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-31/hello_macro/hello_macro_derive/src/lib.rs}}
```
<span class="caption">Listing 20-31: Code that most procedural macro crates
will require in order to process Rust code</span>
</Listing>
Notice that weve split the code into the `hello_macro_derive` function, which
is responsible for parsing the `TokenStream`, and the `impl_hello_macro`
@@ -321,6 +321,8 @@ operations on. This is where `syn` comes into play. The `parse` function in
parsed Rust code. Listing 20-32 shows the relevant parts of the `DeriveInput`
struct we get from parsing the `struct Pancakes;` string:
<Listing number="20-32" caption="The `DeriveInput` instance we get when parsing the code that has the macros attribute in Listing 20-30">
```rust,ignore
DeriveInput {
// --snip--
@@ -341,8 +343,7 @@ DeriveInput {
}
```
<span class="caption">Listing 20-32: The `DeriveInput` instance we get when
parsing the code that has the macros attribute in Listing 20-30</span>
</Listing>
The fields of this struct show that the Rust code weve parsed is a unit struct
with the `ident` (identifier, meaning the name) of `Pancakes`. There are more
@@ -368,14 +369,13 @@ Now that we have the code to turn the annotated Rust code from a `TokenStream`
into a `DeriveInput` instance, lets generate the code that implements the
`HelloMacro` trait on the annotated type, as shown in Listing 20-33.
<span class="filename">Filename: hello_macro_derive/src/lib.rs</span>
<Listing number="20-33" file-name="hello_macro_derive/src/lib.rs" caption="Implementing the `HelloMacro` trait using the parsed Rust code">
```rust,ignore
{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-33/hello_macro/hello_macro_derive/src/lib.rs:here}}
```
<span class="caption">Listing 20-33: Implementing the `HelloMacro` trait using
the parsed Rust code</span>
</Listing>
We get an `Ident` struct instance containing the name (identifier) of the
annotated type using `ast.ident`. The struct in Listing 20-32 shows that when