Reputation: 3383
I have a custom derive macro which generates some code for a struct it is applied to. That code uses few types (bytes::Buf
, ect) that need to be imported.
#[derive(MyMacro)]
struct S { ... }
What is the correct way to handle it?
If I leave it with user to add required imports to a file where my macro is used -- every time macro is changed I run a risk of breaking user code (by introducing new import requirement).
If I add required import to the generated/emitted code -- compiler complain about duplicated imports every time macro is used more than once in the same file. Plus, I run the risk of breaking user code if (after I change the macro) I introduce an import user already used.
Upvotes: 0
Views: 677
Reputation: 22818
Disclaimer: This is just my understanding of the best practices. I can not offer links to official guidelines backing up my claims. So take them with a grain of salt.
I think that macros in general should never do relative imports, or rely user provided external structs/imports. Macros should be self-contained.
If you do need imports, put your generated code in its own scope and add a use
statement there. If you import inside of macros, always use the fully qualified path. That means, if you want to import HashMap
, put a use ::std::collections::HashMap;
inside of the macro. Again, make sure this import doesn't leak out.
Note the ::
in front of it. That annotates that std
is a top level module. Otherwise if the macro is used inside of a user::provided::std
module, the std
would reference this one. Adding the ::
in front of it ensures that it is actually the built-in std
module.
Upvotes: 2