What Is This Thing Anyway?

Have you ever thought about having AI write your function bodies for you - not as IDE autocomplete, but at compile time? The compiler actually reaches out to ChatGPT while building your code?

Sounds crazy, right?

But someone actually did it. There’s an experimental Rust project called ai-bindgen that does exactly this. It uses Rust proc-macros to secretly call OpenAI’s API during cargo build, achieving compile-time AI powered LLM code generation.

Think of it this way: imagine you’re a chef, and your recipe says “Step 3: Make a delicious braised pork.” So you just call a Michelin-star chef and have them tell you exactly how to do it over the phone. The recipe author never wrote the details, but the dish you serve is actually edible.

Reddit users who saw this project immediately labeled it “cursed” - both amazed by its clever hack and worried it might burn them at any moment.

What Does It Look Like?

The code is deceptively simple:

use ai_bindgen::ai;

#[ai]
extern "C" {
    #[ai(prompt = "return the n-th prime number, please")]
    fn prime(n: i32) -> i32;
}

fn main() {
    println!("The 15th prime number is {}", prime(15)); // 47 (hopefully)
}

See that? You just write a function signature, add a prompt telling the AI what you want, and leave the rest to it.

During compilation, this macro will:

  1. Read your function signature and prompt
  2. Send a request to OpenAI (or a compatible API)
  3. Stuff the returned code into the function body
  4. Compile normally, as if you wrote it yourself

If you use cargo expand to inspect the generated code, you’ll find it’s just regular Rust code - loops, conditionals, vector operations, everything you’d expect. The only difference is you didn’t write it; the AI generated it on the fly at compile time.

Code reflected in glasses - the mystery of compile-time AI generation

Wait, Can Rust Proc-Macros Really Do This?

Yes.

Rust proc-macros are essentially “programs that run at compile time.” They receive Rust syntax trees (AST) and output new Rust syntax trees. These macros don’t appear in your final binary; they only run while the compiler is building your code.

And Rust doesn’t actually forbid proc-macros from making network requests. While the community generally believes builds should be “deterministic” and “reproducible,” the language itself doesn’t prohibit shenanigans at compile time.

This crate exploits exactly that freedom in Rust metaprogramming: it takes your function signature and prompt, asks a large language model, and turns the answer into Rust code. This kind of compile-time AI approach is truly eye-opening.

Why It’s Cool

Honestly, the first time I saw this thing, I was pretty excited.

1. A New Way to Explore Programming

You can sketch out a few function signatures, let AI fill in the blanks, and see if the generated code matches what you had in mind. When you run cargo expand and find its implementation is more elegant than yours, it’s like peeking at the top student’s homework before submitting your own.

2. Tremendous Educational Value

This is a living textbook showing how far Rust metaprogramming can go. Where are the boundaries of Rust proc-macro capabilities? This project provides a pretty extreme answer.

3. Great Ergonomics

No switching to a browser, no copy-pasting. Just write your requirements directly in Rust code, and you get results at compile time. The experience is, how should I put it, pretty satisfying.

Why It’s “Cursed”

Alright, let’s be adults here and seriously discuss the pitfalls.

1. Non-Deterministic Builds

The same code compiled today and tomorrow might generate completely different function implementations. The model got updated, network hiccupped, API returned different results - your binary is now different.

This is a cardinal sin in the Rust community. Rust’s philosophy is “reproducible builds,” and CI/CD systems assume this too. This thing throws that premise right out the window.

It’s like calling a different chef every time you make braised pork - one prefers sugar, another prefers salt. Of course the taste won’t be the same.

2. Supply Chain Risk

You’re introducing an external dependency at the most critical point of the compiler, and it’s a mutable dependency at that. API down? Build fails. API returns buggy code? Build succeeds but you ship bugs.

3. Safety and Correctness

The code generated by this macro is fully trusted by the compiler. If the AI generates code with an off-by-one error, or a potential panic, or worse - undefined behavior (UB) - you won’t know unless your tests catch it.

The author themselves says: “potentially dangerous… run at your own risk (ideally in a sandbox).”

4. Compliance Issues

Making network requests during builds leaks metadata (your prompts, function signatures). Some companies have security policies that prohibit any outbound network requests during builds.

Matrix-style code background - the unknown world of compile time

Can I Use It?

Short answer: Not in production.

Long answer: Use the idea, not the mechanism.

Network-based compile-time AI code generation conflicts with reproducible builds, CI workflows, and security policies. But the idea of “AI-assisted programming + human review and verification” is valuable.

A Safer AI-Assisted Programming Approach

If you really want to play with LLM code generation in Rust projects, here’s a more reliable pattern:

1. Gate AI Generation Behind an Explicit Step

Use build.rs or a separate CLI tool to trigger AI generation, like AIGEN=1 cargo run -p gen. Normal builds never touch the network.

2. Commit Generated Code to the Repository

Write AI-generated code to src/gen/*.rs and commit it. Downstream users compile deterministic source code, not prompts.

3. Lock Generation Parameters

Record the model name, prompt, parameters, and seed in a header comment in the generated file. Every regeneration can be diff-audited.

4. Trait-Based Design

Define traits to describe the behaviors you want AI to implement:

// Library code
pub trait NthPrime {
    fn prime(&self, n: i32) -> i32;
}

// Generated code (committed to repo)
pub struct NthPrimeImpl;

impl NthPrime for NthPrimeImpl {
    fn prime(&self, n: i32) -> i32 {
        // AI-generated, but now ordinary, committed Rust code
        /* ... */
    }
}

5. Property Tests as Gatekeepers

Use proptest or fuzzing to verify that generated code satisfies invariants (like primality correctness, monotonicity). Code that fails tests doesn’t get merged.

6. Offline CI by Default

CI only compiles committed .rs files. Regeneration is a separate, opt-in pipeline that requires explicit triggering.

This way you get the convenience of AI-assisted programming while maintaining reproducible builds, auditable diffs, and real test protection.

Code on laptop - a safer development approach

If You Really Want to Play With It

Okay, I know you’re itching to try it. Here’s a safe playground guide:

  1. Read the README warnings, set up OPENAI_API_KEY and OPENAI_API_MODEL
  2. Use a brand new sandbox project with no important code
  3. Always use cargo expand to see what got generated
  4. Write tests for generated functions, don’t blindly trust them
  5. Only use for prototypes, teaching, demos, and blog posts (like this one)

Where Could This Go Next?

I think there are some interesting directions:

  • Prompt schemas + validators: Built-in function contracts (pre/post conditions) that generators must satisfy, with auto-generated tests
  • Retrieval-augmented generation: Feed your own codebase snippets to the model for better consistency
  • AI as scaffolding: Let AI write boilerplate, you write the core logic. For example, generate serde models and mappers, then you fine-tune

Final Thoughts

ai-bindgen is the kind of “off-road” experiment that makes Rust fun - it demonstrates the power (and sharpness) of Rust metaprogramming. As a production guide, it’s a cautionary tale. As a tool for learning Rust proc-macros, it’s gold.

Use AI-assisted programming to accelerate your Rust development - but don’t use it to destabilize your builds. Keep LLM code generation explicit, code committed to repos, tests rock-solid, and builds offline by default. That’s the right approach to compile-time AI.


Project Repository: germangb/ai-bindgen

Related Technologies: ai-bindgen | Rust proc-macro | LLM code generation | compile-time AI | Rust metaprogramming | AI-assisted programming


If you found this article helpful or if it gave you new insights into Rust proc-macros and Rust metaprogramming, consider:

  • Give it a like: Help more people discover this interesting project
  • Share it: Your Rust enthusiast friends might be interested too
  • Bookmark it: Easy to find when you want to play with it later

Got thoughts or questions? Feel free to discuss in the comments. Do you think this kind of “compile-time AI call” is a future trend or just a flash in the pan?