mirror of
https://gitee.com/openharmony/third_party_rust_proc-macro2
synced 2024-11-27 01:20:48 +00:00
Explain post-1.30 purpose of this crate
This commit is contained in:
parent
fd8cdc8a88
commit
7aa1c9cf0e
63
README.md
63
README.md
@ -4,56 +4,73 @@
|
||||
[![Latest Version](https://img.shields.io/crates/v/proc-macro2.svg)](https://crates.io/crates/proc-macro2)
|
||||
[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/proc-macro2)
|
||||
|
||||
A small shim over the `proc_macro` crate in the compiler intended to multiplex
|
||||
the stable interface as of 1.15.0 and the interface as of 1.30.0.
|
||||
A wrapper around the procedural macro API of the compiler's `proc_macro` crate.
|
||||
This library serves three purposes:
|
||||
|
||||
New features added in Rust 1.30.0 include:
|
||||
- **Bring proc-macro-like functionality to other contexts like build.rs and
|
||||
main.rs.** Types from `proc_macro` are entirely specific to procedural macros
|
||||
and cannot ever exist in code outside of a procedural macro. Meanwhile
|
||||
`proc_macro2` types may exist anywhere including non-macro code. By developing
|
||||
foundational libraries like [syn] and [quote] against `proc_macro2` rather
|
||||
than `proc_macro`, the procedural macro ecosystem becomes easily applicable to
|
||||
many other use cases and we avoid reimplementing non-macro equivalents of
|
||||
those libraries.
|
||||
|
||||
* Span information on tokens
|
||||
* No need to go in/out through strings
|
||||
* Structured input/output
|
||||
- **Make procedural macros unit testable.** As a consequence of being specific
|
||||
to procedural macros, nothing that uses `proc_macro` can be executed from a
|
||||
unit test. In order for helper libraries or components of a macro to be
|
||||
testable in isolation, they must be implemented using `proc_macro2`.
|
||||
|
||||
Libraries ported to `proc_macro2` can retain support for older compilers while
|
||||
continuing to get all the nice benefits of using a 1.30.0+ compiler.
|
||||
- **Provide the latest and greatest APIs across all compiler versions.**
|
||||
Procedural macros were first introduced to Rust in 1.15.0 with an extremely
|
||||
minimal interface. Since then, many improvements have landed to make macros
|
||||
more flexible and easier to write. This library tracks the procedural macro
|
||||
API of the most recent stable compiler but employs a polyfill to provide that
|
||||
API consistently across any compiler since 1.15.0.
|
||||
|
||||
[syn]: https://github.com/dtolnay/syn
|
||||
[quote]: https://github.com/dtolnay/quote
|
||||
|
||||
## Usage
|
||||
|
||||
This crate compiles on all 1.15.0+ stable compilers and usage looks like:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
proc-macro2 = "0.4"
|
||||
```
|
||||
|
||||
followed by
|
||||
The skeleton of a typical procedural macro typically looks like this:
|
||||
|
||||
```rust
|
||||
extern crate proc_macro;
|
||||
|
||||
#[proc_macro_derive(MyDerive)]
|
||||
pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input: proc_macro2::TokenStream = input.into();
|
||||
let input = proc_macro2::TokenStream::from(input);
|
||||
|
||||
let output: proc_macro2::TokenStream = {
|
||||
/* transform input */
|
||||
};
|
||||
|
||||
output.into()
|
||||
proc_macro::TokenStream::from(output)
|
||||
}
|
||||
```
|
||||
|
||||
The 1.30.0 compiler is automatically detected and its interfaces are used when
|
||||
available.
|
||||
If parsing with [Syn], you'll use [`parse_macro_input!`] instead to propagate
|
||||
parse errors correctly back to the compiler when parsing fails.
|
||||
|
||||
## Unstable Features
|
||||
[`parse_macro_input!`]: https://docs.rs/syn/0.15/syn/macro.parse_macro_input.html
|
||||
|
||||
`proc-macro2` supports exporting some methods from `proc_macro` which are
|
||||
currently highly unstable, and are not stabilized in the first pass of
|
||||
`proc_macro` stabilizations. These features are not exported by default. Minor
|
||||
versions of `proc-macro2` may make breaking changes to them at any time.
|
||||
## Unstable features
|
||||
|
||||
To enable these features, the `procmacro2_semver_exempt` config flag must be
|
||||
passed to rustc.
|
||||
The default feature set of proc-macro2 tracks the most recent stable compiler
|
||||
API. Functionality in `proc_macro` that is not yet stable is not exposed by
|
||||
proc-macro2 by default.
|
||||
|
||||
To opt into the additional APIs available in the most recent nightly compiler,
|
||||
the `procmacro2_semver_exempt` config flag must be passed to rustc. As usual, we
|
||||
will polyfill those nightly-only APIs all the way back to Rust 1.15.0. As these
|
||||
are unstable APIs that track the nightly compiler, minor versions of proc-macro2
|
||||
may make breaking changes to them at any time.
|
||||
|
||||
```
|
||||
RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build
|
||||
@ -63,6 +80,8 @@ Note that this must not only be done for your crate, but for any crate that
|
||||
depends on your crate. This infectious nature is intentional, as it serves as a
|
||||
reminder that you are outside of the normal semver guarantees.
|
||||
|
||||
Semver exempt methods are marked as such in the proc-macro2 documentation.
|
||||
|
||||
# License
|
||||
|
||||
This project is licensed under either of
|
||||
|
92
src/lib.rs
92
src/lib.rs
@ -1,35 +1,72 @@
|
||||
//! A "shim crate" intended to multiplex the [`proc_macro`] API on to stable
|
||||
//! Rust.
|
||||
//! A wrapper around the procedural macro API of the compiler's [`proc_macro`]
|
||||
//! crate. This library serves three purposes:
|
||||
//!
|
||||
//! Procedural macros in Rust operate over the upstream
|
||||
//! [`proc_macro::TokenStream`][ts] type. This type currently is quite
|
||||
//! conservative and exposed no internal implementation details. Nightly
|
||||
//! compilers, however, contain a much richer interface. This richer interface
|
||||
//! allows fine-grained inspection of the token stream which avoids
|
||||
//! stringification/re-lexing and also preserves span information.
|
||||
//! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/
|
||||
//!
|
||||
//! The upcoming APIs added to [`proc_macro`] upstream are the foundation for
|
||||
//! productive procedural macros in the ecosystem. To help prepare the ecosystem
|
||||
//! for using them this crate serves to both compile on stable and nightly and
|
||||
//! mirrors the API-to-be. The intention is that procedural macros which switch
|
||||
//! to use this crate will be trivially able to switch to the upstream
|
||||
//! `proc_macro` crate once its API stabilizes.
|
||||
//! - **Bring proc-macro-like functionality to other contexts like build.rs and
|
||||
//! main.rs.** Types from `proc_macro` are entirely specific to procedural
|
||||
//! macros and cannot ever exist in code outside of a procedural macro.
|
||||
//! Meanwhile `proc_macro2` types may exist anywhere including non-macro code.
|
||||
//! By developing foundational libraries like [syn] and [quote] against
|
||||
//! `proc_macro2` rather than `proc_macro`, the procedural macro ecosystem
|
||||
//! becomes easily applicable to many other use cases and we avoid
|
||||
//! reimplementing non-macro equivalents of those libraries.
|
||||
//!
|
||||
//! In the meantime this crate also has a `nightly` Cargo feature which
|
||||
//! enables it to reimplement itself with the unstable API of [`proc_macro`].
|
||||
//! This'll allow immediate usage of the beneficial upstream API, particularly
|
||||
//! around preserving span information.
|
||||
//! - **Make procedural macros unit testable.** As a consequence of being
|
||||
//! specific to procedural macros, nothing that uses `proc_macro` can be
|
||||
//! executed from a unit test. In order for helper libraries or components of
|
||||
//! a macro to be testable in isolation, they must be implemented using
|
||||
//! `proc_macro2`.
|
||||
//!
|
||||
//! # Unstable Features
|
||||
//! - **Provide the latest and greatest APIs across all compiler versions.**
|
||||
//! Procedural macros were first introduced to Rust in 1.15.0 with an
|
||||
//! extremely minimal interface. Since then, many improvements have landed to
|
||||
//! make macros more flexible and easier to write. This library tracks the
|
||||
//! procedural macro API of the most recent stable compiler but employs a
|
||||
//! polyfill to provide that API consistently across any compiler since
|
||||
//! 1.15.0.
|
||||
//!
|
||||
//! `proc-macro2` supports exporting some methods from `proc_macro` which are
|
||||
//! currently highly unstable, and may not be stabilized in the first pass of
|
||||
//! `proc_macro` stabilizations. These features are not exported by default.
|
||||
//! Minor versions of `proc-macro2` may make breaking changes to them at any
|
||||
//! time.
|
||||
//! [syn]: https://github.com/dtolnay/syn
|
||||
//! [quote]: https://github.com/dtolnay/quote
|
||||
//!
|
||||
//! To enable these features, the `procmacro2_semver_exempt` config flag must be
|
||||
//! passed to rustc.
|
||||
//! # Usage
|
||||
//!
|
||||
//! The skeleton of a typical procedural macro typically looks like this:
|
||||
//!
|
||||
//! ```edition2018
|
||||
//! extern crate proc_macro;
|
||||
//!
|
||||
//! # const IGNORE: &str = stringify! {
|
||||
//! #[proc_macro_derive(MyDerive)]
|
||||
//! # };
|
||||
//! pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
//! let input = proc_macro2::TokenStream::from(input);
|
||||
//!
|
||||
//! let output: proc_macro2::TokenStream = {
|
||||
//! /* transform input */
|
||||
//! # input
|
||||
//! };
|
||||
//!
|
||||
//! proc_macro::TokenStream::from(output)
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! If parsing with [Syn], you'll use [`parse_macro_input!`] instead to
|
||||
//! propagate parse errors correctly back to the compiler when parsing fails.
|
||||
//!
|
||||
//! [`parse_macro_input!`]: https://docs.rs/syn/0.15/syn/macro.parse_macro_input.html
|
||||
//!
|
||||
//! # Unstable features
|
||||
//!
|
||||
//! The default feature set of proc-macro2 tracks the most recent stable
|
||||
//! compiler API. Functionality in `proc_macro` that is not yet stable is not
|
||||
//! exposed by proc-macro2 by default.
|
||||
//!
|
||||
//! To opt into the additional APIs available in the most recent nightly
|
||||
//! compiler, the `procmacro2_semver_exempt` config flag must be passed to
|
||||
//! rustc. As usual, we will polyfill those nightly-only APIs all the way back
|
||||
//! to Rust 1.15.0. As these are unstable APIs that track the nightly compiler,
|
||||
//! minor versions of proc-macro2 may make breaking changes to them at any time.
|
||||
//!
|
||||
//! ```sh
|
||||
//! RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build
|
||||
@ -39,8 +76,7 @@
|
||||
//! depends on your crate. This infectious nature is intentional, as it serves
|
||||
//! as a reminder that you are outside of the normal semver guarantees.
|
||||
//!
|
||||
//! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/
|
||||
//! [ts]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html
|
||||
//! Semver exempt methods are marked as such in the proc-macro2 documentation.
|
||||
|
||||
// Proc-macro2 types in rustdoc of other crates get linked to here.
|
||||
#![doc(html_root_url = "https://docs.rs/proc-macro2/0.4.25")]
|
||||
|
Loading…
Reference in New Issue
Block a user