Skip to content

Commit

Permalink
Merge pull request rust-lang#412 from Havvy/proc-macros-2
Browse files Browse the repository at this point in the history
Expand Procedural Macro Docs
  • Loading branch information
steveklabnik committed Sep 7, 2018
2 parents 40ebbee + 1975f82 commit 17d009a
Show file tree
Hide file tree
Showing 5 changed files with 341 additions and 33 deletions.
37 changes: 31 additions & 6 deletions src/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ Attributes may appear as any of:

_Inner attributes_, written with a bang ("!") after the hash ("#"), apply to the
item that the attribute is declared within. _Outer attributes_, written without
the bang after the hash, apply to the item or generic parameter that follow the
attribute.
the bang after the hash, apply to the thing that follows the attribute.

Attributes may be applied to many things in the language:

Expand Down Expand Up @@ -82,6 +81,24 @@ fn some_unused_variables() {
}
```

There are three kinds of attributes:

* Built-in attributes
* Macro attributes
* Derive mode helper attributes

## Active and inert attributes

An attribute is either active or inert. During attribute processing, *active
attributes* remove themselves from the thing they are on while *inert attriutes*
stay on.

The `cfg` and `cfg_attr` attributes are active. The `test` attribute is inert
when compiling for tests and active otherwise. Attribute macros are active.
All other attributes are inert.

---

The rest of this page describes or links to descriptions of which attribute
names have meaning.

Expand Down Expand Up @@ -161,14 +178,20 @@ which can be used to control type layout.

- `macro_reexport` on an `extern crate` — re-export the named macros.

- `macro_export` - export a macro for cross-crate usage.
- `macro_export` - export a `macro_rules` macro for cross-crate usage.

- `no_link` on an `extern crate` — even if we load this crate for macros, don't
link it into the output.

See the [macros section of the first edition of the
book](../book/first-edition/macros.html#scoping-and-macro-importexport) for more
information on macro scope.
information on `macro_rules` macro scope.

- `proc_macro` - Defines a [bang macro].

- `proc_macro_derive` - Defines a [derive macro].

- `proc_macro_attribute` - Defines an [attribute macro].

## Miscellaneous attributes

Expand Down Expand Up @@ -525,9 +548,11 @@ You can implement `derive` for your own traits through [procedural macros].
[match expressions]: expressions/match-expr.html
[external blocks]: items/external-blocks.html
[items]: items.html
[attribute macro]: procedural-macros.html#attribute-macros
[bang macro]: procedural-macros.html#bang-macros
[conditional compilation]: conditional-compilation.html
[trait]: items/traits.html
[main]: crates-and-source-files.html
[derive macro]: procedural-macros.html#derive-macros
[trait]: items/traits.html[main]: crates-and-source-files.html
[`Termination`]: ../std/process/trait.Termination.html
[where clause]: items/where-clauses.html
[trait or lifetime bounds]: trait-bounds.html
5 changes: 4 additions & 1 deletion src/conditional-compilation.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ The following configurations must be defined by the implementation:
This can be used to enable extra debugging code in development but not in
production. For example, it controls the behavior of the standard library's
`debug_assert!` macro.
* `proc_macro` - Set when the crate being compiled is being compiled with the
`proc_macro` [crate type].

You can also set another [attribute] based on a `cfg` variable with `cfg_attr`:

Expand All @@ -96,4 +98,5 @@ This is the same as `#[b]` if `a` is set by `cfg`, and nothing otherwise.
Lastly, configuration options can be used in expressions by invoking the `cfg!`
macro: `cfg!(a)` evaluates to `true` if `a` is set, and `false` otherwise.

[attribute]: attributes.html
[attribute]: attributes.html
[crate type]: linkage.html
4 changes: 3 additions & 1 deletion src/items/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ fn test_only() {
The attributes that have meaning on a function are [`cfg`], [`deprecated`],
[`doc`], `export_name`, `link_section`, `no_mangle`, [the lint check
attributes], [`must_use`], [the testing attributes], and [the optimization hint
attributes], [`must_use`], [the procedural macro attributes], [the testing
attributes], and [the optimization hint
attributes].

[external blocks]: items/external-blocks.html
Expand All @@ -147,6 +148,7 @@ attributes].
[attributes]: attributes.html
[`cfg`]: conditional-compilation.html
[the lint check attributes]: attributes.html#lint-check-attributes
[the procedural macro attributes]: procedural-macros.html
[the testing attributes]: attributes.html#testing
[the optimization hint attributes]: attributes.html#optimization-hints
[`deprecated`]: attributes.html#deprecation
Expand Down
31 changes: 19 additions & 12 deletions src/linkage.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# Linkage

The Rust compiler supports various methods to link crates together both
> Note: This section is described more in terms of the compiler than of
> the language.
The compiler supports various methods to link crates together both
statically and dynamically. This section will explore the various methods to
link Rust crates together, and more information about native libraries can be
link crates together, and more information about native libraries can be
found in the [FFI section of the book][ffi].

[ffi]: ../book/ffi.html
Expand Down Expand Up @@ -35,7 +38,7 @@ be ignored in favor of only building the artifacts specified by command line.

* `--crate-type=staticlib`, `#[crate_type = "staticlib"]` - A static system
library will be produced. This is different from other library outputs in that
the Rust compiler will never attempt to link to `staticlib` outputs. The
the compiler will never attempt to link to `staticlib` outputs. The
purpose of this output type is to create a static library containing all of
the local crate's code along with all upstream dependencies. The static
library is actually a `*.a` archive on linux and osx and a `*.lib` file on
Expand All @@ -44,28 +47,29 @@ be ignored in favor of only building the artifacts specified by command line.
dynamic dependencies on other Rust code.

* `--crate-type=cdylib`, `#[crate_type = "cdylib"]` - A dynamic system
library will be produced. This is used when compiling Rust code as
library will be produced. This is used when compiling
a dynamic library to be loaded from another language. This output type will
create `*.so` files on Linux, `*.dylib` files on macOS, and `*.dll` files on
Windows.

* `--crate-type=rlib`, `#[crate_type = "rlib"]` - A "Rust library" file will be
produced. This is used as an intermediate artifact and can be thought of as a
"static Rust library". These `rlib` files, unlike `staticlib` files, are
interpreted by the Rust compiler in future linkage. This essentially means
interpreted by the compiler in future linkage. This essentially means
that `rustc` will look for metadata in `rlib` files like it looks for metadata
in dynamic libraries. This form of output is used to produce statically linked
executables as well as `staticlib` outputs.

* `--crate-type=proc-macro`, `#[crate_type = "proc-macro"]` - The output
produced is not specified, but if a `-L` path is provided to it then the
compiler will recognize the output artifacts as a macro and it can be loaded
for a program. If a crate is compiled with the `proc-macro` crate type it
will forbid exporting any items in the crate other than those functions
tagged `#[proc_macro_derive]` and those functions must also be placed at the
crate root. Finally, the compiler will automatically set the
`cfg(proc_macro)` annotation whenever any crate type of a compilation is the
`proc-macro` crate type.
for a program. Crates compiled with this crate type must only export
[procedural macros]. The compiler will automatically set the `proc_macro`
[configuration option]. The crates are always compiled with the same target
that the compiler itself was built with. For example, if you are executing
the compiler from Linux with an `x86_64` CPU, the target will be
`x86_64-unknown-linux-gnu` even if the crate is a dependency of another crate
being built for a different target.

Note that these outputs are stackable in the sense that if multiple are
specified, then the compiler will produce each form of output at once without
Expand Down Expand Up @@ -124,7 +128,7 @@ dependencies will be used:

In general, `--crate-type=bin` or `--crate-type=lib` should be sufficient for
all compilation needs, and the other options are just available if more
fine-grained control is desired over the output format of a Rust crate.
fine-grained control is desired over the output format of a crate.

## Static and dynamic C runtimes

Expand Down Expand Up @@ -205,3 +209,6 @@ a statically linked binary on MSVC you would execute:
```ignore,notrust
RUSTFLAGS='-C target-feature=+crt-static' cargo build --target x86_64-pc-windows-msvc
```

[configuration option]: conditional-compilation.html
[procedural macros]: procedural-macros.html
Loading

0 comments on commit 17d009a

Please sign in to comment.