Skip to content

Make generated code to be independent of thiserror crate... or maybe not #9

@idubrov

Description

@idubrov

This is something that might be very specific to what we are doing in our codebase.

We currently use failure::Fail for deriving error boilerplate. The way we use it in our codebase is we re-export it from our own "error library API" (which provides few more bits that are typically used in our error handling).

So, our client code can then import everything through our API:

use our_errors::{Fail, SomeOtherThingy};

However, the way failure::Fail derive macro works, it generates references to failure crate, so we have to add it as a dependency to every crate that uses error handling (in addition to the dependency on our own error handling crate).

thiserror would have the same issue in our codebase: it uses this little thiserror::private::AsDynError;, which would require us to add thiserror dependency to all of our crates.

I'm not sure how useful that would be for thiserror in particular, but some procedural macros go extra mile to allow being abstracted away by other crates (for example inventory supports crate = xyz attribute for that purpose).

On one hand, thiserror is not really meant to be embedded in other crates, it doesn't look like this would be very useful. It's just us doing weird (and, maybe, wrong) things.

On the other hand, I feel that pretty much every procedural macro should be somehow abstracted away from its "runtime" crate, similar to how $crate works in macro_rules, just for the "hygiene" reasons, maybe (also, in case crate gets renamed, etc)?

However, maybe, it's not the job of the macros to provide that abstraction and instead the Rust procedural macros framework should have something similar to $crate attribute. Though, due to the dependency ordering, it's not quite clear how exactly that could work...? Maybe, by doing something like:

// re-export and bind `$crate` to `xyz` for this particular re-export of procedural macro. `self` could be used to indicate self crate -- which would work even if crate gets renamed via `Cargo.toml`.
#[crate = xyz]
pub use thiserror_impl::*;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions