proc-macro-crate
proc-macro-crate copied to clipboard
Does not work correctly in procedural macros called from examples
Suppose we have a library crate smol-lib.
When the library is called in context of an example for this library (i.e. smol-lib/examples/smol.rs) trying to look up the name of the same library (smol-lib), this library resolves that the crate is itself.
This makes sense, but, unfortunately, doesn't correspond to the way you would use the crate from an example: you would not write use crate::SmolStruct as inside the library code, but rather use smol_lib::SmolStruct, the same way as you would in a downstream crate.
This is problematic, because it doesn't allow to write examples for the repo using macros and, at the same time, using macros both inside and outside of smol-lib.
Probably some logic should be added to handle the examples case, not sure how it could be done though
Seems quite similar to the problem in #10, but there doesn't seem to be the same magic env var like CARGO_TARGET_TMPDIR described at https://doc.rust-lang.org/cargo/reference/environment-variables.html
Seems quite similar to the problem in #10, but there doesn't seem to be the same magic env var like
CARGO_TARGET_TMPDIRdescribed at https://doc.rust-lang.org/cargo/reference/environment-variables.html
Maybe there exists something similar.
You can use CARGO_CRATE_NAME.
I'm using this and it works as long as you don't name any of your examples the same as your crate:
let htmx = match (
proc_macro_crate::crate_name("htmx"),
std::env::var("CARGO_CRATE_NAME").as_deref(),
) {
(Ok(FoundCrate::Itself), Ok("htmx")) => quote!(crate),
(Ok(FoundCrate::Name(name)), _) => {
let ident = Ident::new(&name, Span::call_site());
quote!(::#ident)
}
_ => quote!(::htmx),
};
Only issue is, rust-analyzer currently has a bug: https://github.com/rust-lang/rust-analyzer/issues/15572
So it turns out this workaroud doesn't work for doctests, because those compile with the same crate name.
I found a solution, that basically allows using ::crate_name inside your crate in place of crate:
You can use
extern crate self as my_crate_name;to make::my_crate_namework even inside your own crate.