<- MyBlog
11th August, 2022
5 min read
Debugging proc macros using croc-look
The terminal solution right now for debugging procedural macros in rust is called cargo-expand which is a good solution but what if,
- You want a declutered, straight to the point view of what your code is generating
- You want to see the output of your macro as your writing it (live reloading)
The reason why I think croc-look
is a good solution is that it allows you to think straight
in terms of the code your generating.
croc-look
will help the community better debug proc macros and make them tiny bit easier to make.
Getting started is as easy as
cargo install croc-look
Let's take a look at this
#[derive(Serialize, Debug, Clone)]
struct T {}
Suppose your the person who's writing the derive macro Serialize
. Your implementing the Serialize
trait for a struct. Now you want to see the whole impl.
➜ croc-look -t Serialize -i T
Is enough to find the impl since there's only one impl in the scope right now. Let's look at edge cases
#[derive(Serialize, Debug, Clone)]
struct T {}
#[derive(Serialize, Debug, Clone)]
struct B {}
mod module {
use super::*;
#[derive(Serialize, Debug, Clone)]
struct C(usize);
#[derive(Serialize, Debug, Clone)]
struct D(u64);
}
The challenge is to look at Serialize impl for each struct we see in the code above. Let's look in the module first
➜ croc-look -p module --trait-impl Serialize -i C
This shows you the impl of Serialize
in the module module
for struct C
. Works the same with nested modules
mod module {
use super::*;
#[derive(Serialize, Debug, Clone)]
struct C(usize);
#[derive(Serialize, Debug, Clone)]
struct D(u64);
mod inner_module {
use super::*;
#[derive(Serialize, Debug, Clone)]
struct E(u64);
}
}
The command croc-look -p module::inner_module --trait-impl Serialize -i E
outputs
impl _serde::Serialize for E {
fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
where
__S: _serde::Serializer,
{
_serde::Serializer::serialize_newtype_struct(__serializer, "E", &self.0)
}
}
This will work without -p module::inner_module
assuming the struct names aren't the same across modules
but it'll be faster to execute if you specify the module since croc-look
will only parse that module.
The --watch
flag
The watch feature is gonna come in handy when your working on big macros. It features a TUI which allows you to see your code live
The left side shows the --watch
flag of croc-look
, right part shows me working on a proc-macro = true
crate
Once you're able to form the command which shows you the macro you want, you are able to use the --watch
flag to watch a particular
directory recursively or even a single file.
Hope this makes proc macros a little bit easier for you!
Links: