codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🦀

Rust

37 / 58 topics
36Macros37Procedural Macros
Tutorials/Rust/Procedural Macros
🦀Rust

Procedural Macros

Updated 2026-05-15
10 min read

Procedural Macros

Introduction

In the world of Rust, macros are a powerful tool that allow you to write code that writes other code. This capability is particularly useful for code generation and abstraction, helping developers reduce boilerplate and increase productivity. In this tutorial, we will dive into procedural macros, which are a type of macro that allows you to generate code at compile time based on the input tokens.

Concept

Procedural macros are functions that take Rust syntax trees as input and produce new Rust syntax trees as output. They are defined using the proc_macro crate, which provides the necessary tools for parsing and manipulating Rust syntax trees. Procedural macros can be categorized into three types:

  1. Function-like Macros: These are invoked like a function call but operate on Rust code.
  2. Derive Macros: These automatically implement traits for your types.
  3. Attribute Macros: These modify the behavior of items like functions or structs.

In this tutorial, we will focus on writing a simple function-like procedural macro that generates a function based on its input.

Examples

Step 1: Setting Up Your Project

First, you need to set up a new Rust project with the necessary dependencies. Open your terminal and run:

Terminal
$ cargo new --lib my_macro_project
$ cd my_macro_project
$ cargo add proc-macro-hack
$ cargo add quote
$ cargo add syn

Step 2: Writing the Procedural Macro

Now, let's create a procedural macro that generates a function. We'll start by defining the macro in src/lib.rs.

Rust
1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, ItemFn};
4
5#[proc_macro]
6pub fn generate_function(input: TokenStream) -> TokenStream {
7 // Parse the input tokens into a syntax tree
8 let func = parse_macro_input!(input as ItemFn);
9
10 // Generate new function name by appending "_generated" to the original function name
11 let new_func_name = &func.sig.ident;
12 let new_func_ident = format!("{}_generated", new_func_name);
13 let new_func_ident = syn::Ident::new(&new_func_ident, func.span());
14
15 // Generate the new function body
16 let expanded = quote! {
17 fn #new_func_ident() {
18 println!("Generated function called!");
19 }
20 };
21
22 TokenStream::from(expanded)
23}

Step 3: Using the Procedural Macro

Next, we'll use our macro in another file. Create a new file src/main.rs and add the following code:

Rust
1extern crate my_macro_project;
2
3use my_macro_project::generate_function;
4
5// Define a function that will be used as input for the macro
6fn example_function() {
7 println!("Original function called!");
8}
9
10// Use the procedural macro to generate a new function
11generate_function!(example_function);
12
13fn main() {
14 // Call both functions to see the output
15 example_function();
16 example_function_generated();
17}

Step 4: Running the Code

Compile and run your project using Cargo:

Terminal
$ cargo build --release
$ ./target/release/my_macro_project
Original function called!
Generated function called!

You should see the output from both the original and generated functions, demonstrating that our procedural macro successfully created a new function based on the input.

What's Next?

In this tutorial, we covered the basics of writing procedural macros for code generation. In the next section, we will explore attribute macros, which allow you to modify the behavior of items like functions or structs. Understanding both types of macros will give you powerful tools for enhancing your Rust projects with compile-time code generation and abstraction.

Info

Remember that procedural macros are a powerful feature but should be used judiciously to maintain code readability and maintainability.

PreviousMacrosNext Attributes

Recommended Gear

MacrosAttributes