A derive macro that generates trait impls.
We are deriving the HeapSize
trait which computes an estimate of the amount of
heap memory owned by a value.
pub trait HeapSize {
/// Total number of bytes of heap memory owned by `self`.
fn heap_size_of_children(&self) -> usize;
}
The derive macro allows users to write #[derive(HeapSize)]
on data structures
in their program.
#[derive(HeapSize)]
struct Demo<'a, T: ?Sized> {
a: Box<T>,
b: u8,
c: &'a str,
d: String,
}
The trait impl generated by the derive macro here would look like:
impl<'a, T: ?Sized + heapsize::HeapSize> heapsize::HeapSize for Demo<'a, T> {
fn heap_size_of_children(&self) -> usize {
0 + heapsize::HeapSize::heap_size_of_children(&self.a)
+ heapsize::HeapSize::heap_size_of_children(&self.b)
+ heapsize::HeapSize::heap_size_of_children(&self.c)
+ heapsize::HeapSize::heap_size_of_children(&self.d)
}
}
The implementation of heapsize_derive
demonstrates some attention to "spans"
of error messages. For each subexpression in the generated code we apply the
span of the input fragment under which we would want to trigger a compiler error
if the subexpression fails to compile. In this example, each recursive call to
heap_size_of_children
is associated with the span of the corresponding struct
field. Thus we get errors in the right place if any of the field types do not
implement the HeapSize
trait.
error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied
--> src/main.rs:7:5
|
7 | bad: std::thread::Thread,
| ^^^ the trait `HeapSize` is not implemented for `std::thread::Thread`
Some unstable APIs in the proc-macro2
crate let us improve this further by
joining together the span of the field name and the field type. There is no
difference in our code — everything is as shown in this directory —
but building the example crate with cargo build
shows errors like the one
above and building with RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build
is able to show errors like the following.
error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied
--> src/main.rs:7:5
|
7 | bad: std::thread::Thread,
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `std::thread::Thread`