Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

equivalent of $crate in custom derive paths #507

Closed
dhardy opened this issue Sep 28, 2018 · 7 comments
Closed

equivalent of $crate in custom derive paths #507

dhardy opened this issue Sep 28, 2018 · 7 comments

Comments

@dhardy
Copy link
Contributor

dhardy commented Sep 28, 2018

With declarative macros I can use $crate to specify fully-qualified paths in a way that works both in the parent crate and when exported to other crates. Is there an equivalent for procedural macros?

::mylib::MyType doesn't work within mylib. Before "edition 2018", a workaround like this would probably have been possible, but I don't believe it is any longer:

// in crate root:
mod mylib {
    pub use super::*;
}

Considering that these macros must currently be defined in another crate it is of course more complicated; a simple $crate would expand to the wrong thing.

@dtolnay
Copy link
Owner

dtolnay commented Sep 28, 2018

I don't know of a 2018 workaround for this. Your mylib crate may need to remain on 2015 edition until this is supported. The macro would be able to reference items from mylib like this:

{
    use mylib as _mylib;
    _mylib::MyType
}

This is what Diesel does.
https://github.com/diesel-rs/diesel/blob/42d5b831ac6b407c74a3659653f5b9d171730851/diesel/src/lib.rs#L358-L360

@dtolnay
Copy link
Owner

dtolnay commented Sep 28, 2018

@alexcrichton any ideas for how to make this work when mylib is on 2018 edition?

@alexcrichton
Copy link
Collaborator

Hm I may be missing something, but why doesn't the mod mylib { ... } trick work in 2018?

@dtolnay
Copy link
Owner

dtolnay commented Sep 28, 2018

You can't refer to items from mod mylib in a unified way that works both in downstream crates as well as inside of mylib. In 2018, the first segment of a use statement always identifies a crate. So within mylib it would only work if the procedural macro expands to use crate::mylib::MyType while in downstream crates it would only work as use mylib::MyType.

@alexcrichton
Copy link
Collaborator

Ah right yes, ::mylib::MyType only works in 2018 if mylib is a crate.

It's possible to have the same procedural macro do something like __flag_im_in_my_own_crate!() which sets some sort of global variable which causes all path emissions to use crate::... instead of just ::.... That's pretty awful though and I wouldn't necessarily recommend it.

All in all, sounds like we don't have a solution right now and these crates need to stay on the 2015 edition.

@eddyb
Copy link

eddyb commented Sep 28, 2018

The global variable thing isn't even guaranteed to work - expansion order is unspecified.
(also unspecified: whether global/thread-local variables are preserved across invocations)

@dtolnay
Copy link
Owner

dtolnay commented Sep 29, 2018

Closing in favor of rust-lang/rust#54647 to keep the discussion in one place.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants