Rust proc-macro crate not available — Macro Import Fails
Fix "proc-macro crate not available" and unresolved derive errors by separating the proc-macro crate and importing derives through the facade.
Symptoms
- error: proc-macro crates cannot export items other than macros
- error[E0433]: failed to resolve: could not find `X` in `Y`
- Deriving a macro fails only in downstream crates
Possible causes
- A proc-macro crate tries to export regular items or is used as a normal dependency
- The derive macro is defined in a crate without proc-macro = true
- Macros are re-exported without the required pub use or a facade crate
Diagnosis steps
Verify the crate type
grep -n "proc-macro" Cargo.tomlInterpretation
A derive-defining crate must declare proc-macro = true under [lib]; otherwise it cannot define derives.
Reproduce the resolve error
cargo build 2>&1 | grep -E "proc-macro|E0433" | headInterpretation
The resolution failure names the crate and item, showing whether the export or the dependency is wrong.
Root cause
A proc-macro crate compiles to a compiler plugin and may only export macros. If it also exports traits or functions, the build fails; consumers must import the macro through the crate that legally exports it.
Fix
Split the crate so the proc-macro crate only defines macros, move shared items to a normal library crate, and re-export derives through a facade so users import one crate.
Risk note
Changing the crate type can break existing import paths; provide a facade and deprecate the old path gradually.
Verify the fix
cargo build succeeds and a downstream crate derives the macro; cargo doc shows the macro exported from the facade.
Symptoms
This debugging guide addresses “Rust proc-macro crate not available — Macro Import Fails”. Start from the symptoms, follow the ordered diagnostics, and confirm each hypothesis before moving on; the fix and verification steps then close the loop.
Observed symptoms include:
- error: proc-macro crates cannot export items other than macros
- error[E0433]: failed to resolve: could not find
XinY - Deriving a macro fails only in downstream crates
Reproduce and Diagnose
Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.
Step 1: Verify the crate type
grep -n "proc-macro" Cargo.toml
A derive-defining crate must declare proc-macro = true under [lib]; otherwise it cannot define derives.
Step 2: Reproduce the resolve error
cargo build 2>&1 | grep -E "proc-macro|E0433" | head
The resolution failure names the crate and item, showing whether the export or the dependency is wrong.
Likely contributors, in order of frequency:
- A proc-macro crate tries to export regular items or is used as a normal dependency
- The derive macro is defined in a crate without proc-macro = true
- Macros are re-exported without the required pub use or a facade crate
Root Cause
A proc-macro crate compiles to a compiler plugin and may only export macros. If it also exports traits or functions, the build fails; consumers must import the macro through the crate that legally exports it.
The Fix
Split the crate so the proc-macro crate only defines macros, move shared items to a normal library crate, and re-export derives through a facade so users import one crate.
Watch out: Changing the crate type can break existing import paths; provide a facade and deprecate the old path gradually.
# Cargo.toml of the proc-macro crate
[lib]
proc-macro = true
[dependencies]
syn = "2"
quote = "1"
# Facade crate re-exports the derive so users import one path
# lib.rs
pub use my_derive::MyTrait;
Verify and Prevent
cargo build succeeds and a downstream crate derives the macro; cargo doc shows the macro exported from the facade.
Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.
This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.