]> git.proxmox.com Git - cargo.git/blobdiff - vendor/proc-macro2/src/lib.rs
New upstream version 0.33.0
[cargo.git] / vendor / proc-macro2 / src / lib.rs
index db51272275abc275019ca85209f12aef6c602c2b..25dd705c2e4cc068206fb850919b04e137067d21 100644 (file)
@@ -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/
+//!
+//! - **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.
+//!
+//! - **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`.
+//!
+//! - **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
+//!
+//! The skeleton of a typical procedural macro typically looks like this:
+//!
+//! ```edition2018
+//! extern crate 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.
+//! # 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);
 //!
-//! 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.
+//!     let output: proc_macro2::TokenStream = {
+//!         /* transform input */
+//!         # input
+//!     };
 //!
-//! # Unstable Features
+//!     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
 //!
-//! `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.
+//! 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 enable these features, the `procmacro2_semver_exempt` config flag must be
-//! passed to rustc.
+//! 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
 //! 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.24")]
-#![cfg_attr(
-    super_unstable,
-    feature(proc_macro_raw_ident, proc_macro_span, proc_macro_def_site)
-)]
+#![doc(html_root_url = "https://docs.rs/proc-macro2/0.4.27")]
+#![cfg_attr(nightly, feature(proc_macro_span))]
+#![cfg_attr(super_unstable, feature(proc_macro_raw_ident, proc_macro_def_site))]
 
 #[cfg(use_proc_macro)]
 extern crate proc_macro;
@@ -65,11 +99,11 @@ use std::str::FromStr;
 
 #[macro_use]
 mod strnom;
-mod stable;
+mod fallback;
 
 #[cfg(not(wrap_proc_macro))]
-use stable as imp;
-#[path = "unstable.rs"]
+use fallback as imp;
+#[path = "wrapper.rs"]
 #[cfg(wrap_proc_macro)]
 mod imp;
 
@@ -100,7 +134,7 @@ impl TokenStream {
         }
     }
 
-    fn _new_stable(inner: stable::TokenStream) -> TokenStream {
+    fn _new_stable(inner: fallback::TokenStream) -> TokenStream {
         TokenStream {
             inner: inner.into(),
             _marker: marker::PhantomData,
@@ -266,7 +300,7 @@ impl fmt::Debug for SourceFile {
 /// A line-column pair representing the start or end of a `Span`.
 ///
 /// This type is semver exempt and not exposed by default.
-#[cfg(procmacro2_semver_exempt)]
+#[cfg(span_locations)]
 pub struct LineColumn {
     /// The 1-indexed line in the source file on which the span starts or ends
     /// (inclusive).
@@ -291,7 +325,7 @@ impl Span {
         }
     }
 
-    fn _new_stable(inner: stable::Span) -> Span {
+    fn _new_stable(inner: fallback::Span) -> Span {
         Span {
             inner: inner.into(),
             _marker: marker::PhantomData,
@@ -333,11 +367,26 @@ impl Span {
         Span::_new(self.inner.located_at(other.inner))
     }
 
-    /// This method is only available when the `"nightly"` feature is enabled.
+    /// Convert `proc_macro2::Span` to `proc_macro::Span`.
+    ///
+    /// This method is available when building with a nightly compiler, or when
+    /// building with rustc 1.29+ *without* semver exempt features.
+    ///
+    /// # Panics
+    ///
+    /// Panics if called from outside of a procedural macro. Unlike
+    /// `proc_macro2::Span`, the `proc_macro::Span` type can only exist within
+    /// the context of a procedural macro invocation.
+    #[cfg(wrap_proc_macro)]
+    pub fn unwrap(self) -> proc_macro::Span {
+        self.inner.unwrap()
+    }
+
+    // Soft deprecated. Please use Span::unwrap.
+    #[cfg(wrap_proc_macro)]
     #[doc(hidden)]
-    #[cfg(any(feature = "nightly", super_unstable))]
     pub fn unstable(self) -> proc_macro::Span {
-        self.inner.unstable()
+        self.unwrap()
     }
 
     /// The original source file into which this span points.
@@ -350,8 +399,8 @@ impl Span {
 
     /// Get the starting line/column in the source file for this span.
     ///
-    /// This method is semver exempt and not exposed by default.
-    #[cfg(procmacro2_semver_exempt)]
+    /// This method requires the `"span-locations"` feature to be enabled.
+    #[cfg(span_locations)]
     pub fn start(&self) -> LineColumn {
         let imp::LineColumn { line, column } = self.inner.start();
         LineColumn {
@@ -362,8 +411,8 @@ impl Span {
 
     /// Get the ending line/column in the source file for this span.
     ///
-    /// This method is semver exempt and not exposed by default.
-    #[cfg(procmacro2_semver_exempt)]
+    /// This method requires the `"span-locations"` feature to be enabled.
+    #[cfg(span_locations)]
     pub fn end(&self) -> LineColumn {
         let imp::LineColumn { line, column } = self.inner.end();
         LineColumn {
@@ -487,8 +536,7 @@ impl fmt::Debug for TokenTree {
             TokenTree::Ident(ref t) => {
                 let mut debug = f.debug_struct("Ident");
                 debug.field("sym", &format_args!("{}", t));
-                #[cfg(any(feature = "nightly", procmacro2_semver_exempt))]
-                debug.field("span", &t.span());
+                imp::debug_span_field_if_nontrivial(&mut debug, t.span().inner);
                 debug.finish()
             }
             TokenTree::Punct(ref t) => t.fmt(f),
@@ -527,12 +575,10 @@ pub enum Delimiter {
 
 impl Group {
     fn _new(inner: imp::Group) -> Self {
-        Group {
-            inner: inner,
-        }
+        Group { inner: inner }
     }
 
-    fn _new_stable(inner: stable::Group) -> Self {
+    fn _new_stable(inner: fallback::Group) -> Self {
         Group {
             inner: inner.into(),
         }
@@ -699,8 +745,7 @@ impl fmt::Debug for Punct {
         let mut debug = fmt.debug_struct("Punct");
         debug.field("op", &self.op);
         debug.field("spacing", &self.spacing);
-        #[cfg(procmacro2_semver_exempt)]
-        debug.field("span", &self.span);
+        imp::debug_span_field_if_nontrivial(&mut debug, self.span.inner);
         debug.finish()
     }
 }
@@ -727,9 +772,7 @@ impl fmt::Debug for Punct {
 /// A span must be provided explicitly which governs the name resolution
 /// behavior of the resulting identifier.
 ///
-/// ```rust
-/// extern crate proc_macro2;
-///
+/// ```edition2018
 /// use proc_macro2::{Ident, Span};
 ///
 /// fn main() {
@@ -741,13 +784,9 @@ impl fmt::Debug for Punct {
 ///
 /// An ident can be interpolated into a token stream using the `quote!` macro.
 ///
-/// ```rust
-/// #[macro_use]
-/// extern crate quote;
-///
-/// extern crate proc_macro2;
-///
+/// ```edition2018
 /// use proc_macro2::{Ident, Span};
+/// use quote::quote;
 ///
 /// fn main() {
 ///     let ident = Ident::new("demo", Span::call_site());
@@ -764,9 +803,7 @@ impl fmt::Debug for Punct {
 /// A string representation of the ident is available through the `to_string()`
 /// method.
 ///
-/// ```rust
-/// # extern crate proc_macro2;
-/// #
+/// ```edition2018
 /// # use proc_macro2::{Ident, Span};
 /// #
 /// # let ident = Ident::new("another_identifier", Span::call_site());
@@ -954,7 +991,7 @@ impl Literal {
         }
     }
 
-    fn _new_stable(inner: stable::Literal) -> Literal {
+    fn _new_stable(inner: fallback::Literal) -> Literal {
         Literal {
             inner: inner.into(),
             _marker: marker::PhantomData,