Is there a way to have a public trait in a proc-macro crate?

北战南征 提交于 2021-02-16 21:20:47

问题


I have a proc-macro crate with a macro that, when expanded, needs to use custom trait implementations for Rust built-in types. I tried to define the trait in the same crate, but Rust tells me that a proc-macro crate can only have public macros (the functions annotated with #[proc_macro]) and nothing else can be public. So I put the trait in another crate and in the proc-macro crate included it as a dependency. But this means that anyone that wants to use my proc-macro crate has to depend on the other trait crate too.

So I wonder if there is a way to add a public trait to the proc-macro crate, or otherwise to make the proc-macro and trait crates linked in some way so the end user can't try to use one without the other? If neither is possible, the only solution is documenting the dependency, which is kind of fragile.


回答1:


The way this is usually dealt with is to not have users depend on your proc-macro crate at all.

Your problem can be solved with 3 crates:

  • "internal" crate containing type and trait definitions that are used by the proc-macro
  • proc-macro crate:
    • Depends on the internal crate, so it can use its types and traits
  • "public" crate:
    • Depends on both the internal and proc-macro crates
    • Re-exports all types, traits and macros that you want your users to use

Whenever your macro mentions the shared types in its generated code, you need to use the fully-qualified names so that users don't also need to import them.


Some popular examples of this pattern in the wild:

  • thiserror depends on thiserror-impl which contains the actual macros
  • pin-project depends on pin-project-internal which again contains the macros
  • darling depends on darling-core and darling-macro, which itself also depends on darling-core


来源:https://stackoverflow.com/questions/64288426/is-there-a-way-to-have-a-public-trait-in-a-proc-macro-crate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!