I have a problem with the layout of proc macro crates. I have a library crate (let's call it foo
), which exports a trait Bar
. Ideally, it also provides a derive macro but, since foo
also uses declarative macros, I have to create a separate crate for this (let's call it foo-derive
).
Now, the trait Bar
is also implemented within foo
, so I would like foo
to depend on foo-derive
so that I can use #[derive(Bar)]
in foo
. On the other hand, foo-derive
uses fully-qualified path names for the types and traits it uses in foo, so for instance it would impl ::foo::Bar for ... { ... }
.
This works in any library that depends on foo
, but not in foo
itself, for which the path should be crate::Bar
. Also, I can't make foo-derive
publicly re-export the trait Bar
in foo
so that I can use ::foo_derive::Bar
instead, because then I would have a circular dependency between foo
and foo-derive
. Is there a way to solve this (ie. provide derive macros for everyone)?
Here is an answer to your question that I've written in a different topic, hope that helps you:
The extern crate self as foo
Just Works for me, however it's:
- a bit hacky: it's not entirely clear to someone who reads the code why is that even useful in the first place;
- a bit fragile: I've realized (I knew that but it didn't occur to me) that people can rename the dependency
foo
(or even not have it at all), and it will completely break the code.
However, while reading the discussion linked by @nerditation, I found a reference to the proc-macro-crate crate, which solves all these issues. Given the name of the crate foo
, it will fetch in Cargo.toml
whether this crate is a dependency (or is the current crate), and in this case, provide the actual name (ie. after renaming) or crate
if it's the current crate. This doesn't seem to be reliable if there is no Cargo.toml
but, at this point, there is nothing more I can do I think.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.