Struct syn::Attribute

source ·
pub struct Attribute {
    pub pound_token: Pound,
    pub style: AttrStyle,
    pub bracket_token: Bracket,
    pub meta: Meta,
}
Expand description

An attribute, like #[repr(transparent)].


Syntax

Rust has six types of attributes.

  • Outer attributes like #[repr(transparent)]. These appear outside or in front of the item they describe.

  • Inner attributes like #![feature(proc_macro)]. These appear inside of the item they describe, usually a module.

  • Outer one-line doc comments like /// Example.

  • Inner one-line doc comments like //! Please file an issue.

  • Outer documentation blocks /** Example */.

  • Inner documentation blocks /*! Please file an issue */.

The style field of type AttrStyle distinguishes whether an attribute is outer or inner.

Every attribute has a path that indicates the intended interpretation of the rest of the attribute’s contents. The path and the optional additional contents are represented together in the meta field of the attribute in three possible varieties:

  • Meta::Path — attributes whose information content conveys just a path, for example the #[test] attribute.

  • Meta::List — attributes that carry arbitrary tokens after the path, surrounded by a delimiter (parenthesis, bracket, or brace). For example #[derive(Copy)] or #[precondition(x < 5)].

  • Meta::NameValue — attributes with an = sign after the path, followed by a Rust expression. For example #[path = "sys/windows.rs"].

All doc comments are represented in the NameValue style with a path of “doc”, as this is how they are processed by the compiler and by macro_rules! macros.

#[derive(Copy, Clone)]
  ~~~~~~Path
  ^^^^^^^^^^^^^^^^^^^Meta::List

#[path = "sys/windows.rs"]
  ~~~~Path
  ^^^^^^^^^^^^^^^^^^^^^^^Meta::NameValue

#[test]
  ^^^^Meta::Path

Parsing from tokens to Attribute

This type does not implement the Parse trait and thus cannot be parsed directly by ParseStream::parse. Instead use ParseStream::call with one of the two parser functions [Attribute::parse_outer] or [Attribute::parse_inner] depending on which you intend to parse.

use syn::{Attribute, Ident, Result, Token};
use syn::parse::{Parse, ParseStream};

// Parses a unit struct with attributes.
//
//     #[path = "s.tmpl"]
//     struct S;
struct UnitStruct {
    attrs: Vec<Attribute>,
    struct_token: Token![struct],
    name: Ident,
    semi_token: Token![;],
}

impl Parse for UnitStruct {
    fn parse(input: ParseStream) -> Result<Self> {
        Ok(UnitStruct {
            attrs: input.call(Attribute::parse_outer)?,
            struct_token: input.parse()?,
            name: input.parse()?,
            semi_token: input.parse()?,
        })
    }
}


Parsing from Attribute to structured arguments

The grammar of attributes in Rust is very flexible, which makes the syntax tree not that useful on its own. In particular, arguments of the Meta::List variety of attribute are held in an arbitrary tokens: TokenStream. Macros are expected to check the path of the attribute, decide whether they recognize it, and then parse the remaining tokens according to whatever grammar they wish to require for that kind of attribute. Use parse_args() to parse those tokens into the expected data structure.


Doc comments

The compiler transforms doc comments, such as /// comment and /*! comment */, into attributes before macros are expanded. Each comment is expanded into an attribute of the form #[doc = r"comment"].

As an example, the following mod items are expanded identically:

let doc: ItemMod = parse_quote! {
    /// Single line doc comments
    /// We write so many!
    /**
     * Multi-line comments...
     * May span many lines
     */
    mod example {
        //! Of course, they can be inner too
        /*! And fit in a single line */
    }
};
let attr: ItemMod = parse_quote! {
    #[doc = r" Single line doc comments"]
    #[doc = r" We write so many!"]
    #[doc = r"
     * Multi-line comments...
     * May span many lines
     "]
    mod example {
        #![doc = r" Of course, they can be inner too"]
        #![doc = r" And fit in a single line "]
    }
};
assert_eq!(doc, attr);

Fields§

§pound_token: Pound§style: AttrStyle§bracket_token: Bracket§meta: Meta

Implementations§

Returns the path that identifies the interpretation of this attribute.

For example this would return the test in #[test], the derive in #[derive(Copy)], and the path in #[path = "sys/windows.rs"].

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.