Skip to content

Attributes are reordered before they are passed to a proc-macro #67839

Closed

Description

@Luro02

I am working on a proc-macro, where I would like to give the user the option, to decide, which attributes (and doc comments) should be forwarded.

For example

use shorthand::ShortHand;

#[derive(ShortHand)]
#[shorthand(enable(forward(doc)))]
/// This should be in the output
#[shorthand(disable(forward(doc)))]
/// This line should not.
#[shorthand(enable(forward(doc)))]
/// This should be in the output
struct Example {
    value: String,
}

as you can see in the above case, the order of the attributes is very important.
Sadly the rust compiler (or the proc_macro crate) does reorder the attributes, before passing them to the function as a TokenStream.

#![feature(prelude_import)]
#[prelude_import]                                                               
use std::prelude::v1::*;                                                        
#[macro_use]                                                                    
extern crate std;                                                               
use shorthand::ShortHand;                                                       
/// This should be in the output
/// This line should not.                                                       
/// This should be in the output                                                
#[shorthand(enable(forward(doc)))]
#[shorthand(disable(forward(doc)))]                                             
#[shorthand(enable(forward(doc)))]
struct Example {
    value: String,
}
#[allow(dead_code)]
impl Example {
    #[inline(always)]
    pub fn value(&self) -> &String {
        &self.value
    }
    #[inline(always)]
    pub fn set_value(&mut self, value: String) -> &mut Self {
        self.value = value;
        self
    }
}
#[allow(dead_code)]
fn main() {}
#[main]
pub fn main() -> () {
    extern crate test;
    test::test_main_static(&[])
}

(this is the output of cargo expand, the proc-macro gets a similar TokenStream, where the order is not preserved either)

I think this should not happen and the order should be preserved! Are there any good reasons for reordering them?

related to #36211

Activity

  1. changed the title [-]Struct attributes are reordered before they are passed to a proc-macro[/-] [+]Attributes are reordered before they are passed to a proc-macro[/+] on Jan 3, 2020
  2. self-assigned this
    on Jan 3, 2020
  3. petrochenkov commented on Jan 3, 2020

    @petrochenkov
    Contributor

    I agree that the relative order of inert attributes should be kept.
    The reordering happens because built-in attributes (like doc comments) and non-builtin attributes are treated differently by macro expansion infrastructure.

    I plan to fix this during the upcoming macro invocation collector rewrite (#54727 (comment)), unless someone gets to it earlier (this should be doable without rewriting the invocation collector entirely).

    cc #63221

  4. Luro02 commented on Jan 3, 2020

    @Luro02
    ContributorAuthor

    I think this change can wait, until the new macro system is implemented, becuse this would be a breaking change either way. (for example the code given above would have different output, if a macro relies on the current order of attributes)

  5. added
    A-attributesArea: Attributes (`#[…]`, `#![…]`)
    A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jan 3, 2020
  6. pksunkara commented on Nov 5, 2020

    @pksunkara
    Contributor

    Would this issue also include the proposal of ordering from rust-lang/reference#565 (comment)? If I currently write,

    #[foo]
    #[derive(Bar)]

    As far as I observed: foo proc macro doesn't seem to get derive attribute because it looks like derive is expanded before it.

  7. petrochenkov commented on Feb 22, 2021

    @petrochenkov
    Contributor

    Fixed in #82419.

    @pksunkara
    I think your case is different, but it was recently addressed by #79078.

  8. pksunkara commented on Feb 22, 2021

    @pksunkara
    Contributor

    @petrochenkov Really appreciate your hard work in fixing both the issues. I have reworked some of my APIs to not run into this, but I am happy that I can now pick the best ergonomics for my proc-macro libraries instead of trying to navigate these issues.

  9. added 5 commits that reference this issue on Feb 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-attributesArea: Attributes (`#[…]`, `#![…]`)A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)C-enhancementCategory: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions