Git Product home page Git Product logo

Comments (2)

Lokathor avatar Lokathor commented on September 25, 2024

https://github.com/Lokathor/bytemuck/blob/main/derive/src/traits.rs#L93 (and the similar methods on the other derives) seems to be the offender. They're always using ::bytemuck (with the absolute prefix) rather than bytemuck (no prefix).

I'm not super familiar with the derive code, but given that it's deriving unsafe traits i think the extra caution in the import path is probably appropriate.

If someone can submit a PR to fix this without causing potential problems with other traits under the same name ending up derivable and leading to strange bugs I'm all for that. Otherwise I might just say that in this particular case people should just use the full import path to work around this problem. Safety beats ergonomics in this case.

from bytemuck.

danielhenrymantilla avatar danielhenrymantilla commented on September 25, 2024

This is a known hard problem for proc-macros. I've been recently re-thinking about this, and here is the least-bad solution I can think of:

  1. Make ::bytemuck export a hidden-ish new proc-macro derive, say ZeroableUnqualified, which acts like Zeroable but for not prefixing bytemuck with the :: disambiguator.

  2. Then any dependency that wishes to re-export Zeroable, such as the OP's, can then do:

    pub mod bytemuck {
        pub use ::bytemuck::{*, ZeroableUnqualified as Zeroable};
    }
  3. A 2nd-degree dependency can then do:

    pub use ::middle_crate::bytemuck;
    
    #[derive(, bytemuck::Zeroable)]
    struct Foo

    or

    pub use ::middle_crate::bytemuck::{self, Zeroable};
    
    #[derive(, Zeroable)]
    struct Foo

Another approach, more classic but imho more cumbersome for the 2nd-degree dependency, would be for Zeroable to take an optional #[zeroable(crate = …)] parameter with which to override the currently hard-coded ::bytemuck.

This could even palliate a bit better the unsafe-ty @Lokathor was legitimately concerned about1: it's easy to change #[zeroable(crate = …)] to #[zeroable(unsafe { crate = … })], for instance.

At that point the ::middle_crate can keep using pub use ::bytemuck;, as usual, and the 2nd-degree dependency would have to write:

pub use ::middle_crate::bytemuck::{self, Zeroable};

#[derive(, Zeroable)]
#[zeroable(unsafe { crate = bytemuck })]
// or
#[zeroable(unsafe { crate = ::middle_crate::bytemuck })]
struct Foo
  • A variant of this approach, if ::middle_crate is motivated enough, would be for them to re-export their own Zeroable derive, one which would emit:

    #[::middle_crate::__internals::nested_derive(::middle_crate::bytemuck::Zeroable)]
    #[zeroable(unsafe { crate = ::middle_crate::bytemuck })]
    #input
    • where nested_derive is a helper proc-macro I'll be releasing for use cases such as this one 😅

    • A variant of this variant would be to use #[macro_rules_derive], so as to "just" write, from within ::middle_crate a macro_rules! definition:

      #[macro_export]
      macro_rules! Zeroable {( $input:item ) => (
          #[$crate::__internals::nested_derive($crate::bytemuck::Zeroable)]
          #[zeroable(unsafe { crate = $crate::bytemuck })]
          $input
      )}

      so that the 2nd-degree dependency could write:

      use ::middle_crate::prelude::{derive, Zeroable};
      
      #[derive(Zeroable!)]
      struct Foo
      • where derive would then be a re-export of a slightly tweaked version of #[macro_rules_derive] (which I'd also have to publish, but it would be quick)

Footnotes

  1. that being said, the story of macros and unsafety is known to be quite disappointing; the current realistic status quo is that the macro callsites are expected not to go to crazy with renamings and shadowings

from bytemuck.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.