1355 lines · 44.4 KB · Rust
RawDownload
// SPDX-License-Identifier: Apache-2.0 OR MIT // When fixdep scans this, it will find this string `CONFIG_RUSTC_VERSION_TEXT`// and thus add a dependency on `include/config/RUSTC_VERSION_TEXT`, which is// touched by Kconfig when the version string from the compiler changes. //! [![github]](https://github.com/dtolnay/proc-macro2)&ensp;[![crates-io]](https://crates.io/crates/proc-macro2)&ensp;[![docs-rs]](crate)//!//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs//!//! <br>//!//! A wrapper around the procedural macro API of the compiler's [`proc_macro`]//! crate. This library serves two purposes://!//! - **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`.//!//! [syn]: https://github.com/dtolnay/syn//! [quote]: https://github.com/dtolnay/quote//!//! # Usage//!//! The skeleton of a typical procedural macro typically looks like this://!//! ```//! extern crate proc_macro;//!//! # const IGNORE: &str = stringify! {//! #[proc_macro_derive(MyDerive)]//! # };//! # #[cfg(wrap_proc_macro)]//! 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/2.0/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. We will polyfill those nightly-only APIs back to Rust 1.56.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//! ```//!//! 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.//!//! # Thread-Safety//!//! Most types in this crate are `!Sync` because the underlying compiler//! types make use of thread-local memory, meaning they cannot be accessed from//! a different thread. // Proc-macro2 types in rustdoc of other crates get linked to here.#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.101")]#![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))]#![cfg_attr(super_unstable, feature(proc_macro_def_site))]#![cfg_attr(docsrs, feature(doc_cfg))]#![deny(unsafe_op_in_unsafe_fn)]#![allow(    clippy::cast_lossless,    clippy::cast_possible_truncation,    clippy::checked_conversions,    clippy::doc_markdown,    clippy::elidable_lifetime_names,    clippy::incompatible_msrv,    clippy::items_after_statements,    clippy::iter_without_into_iter,    clippy::let_underscore_untyped,    clippy::manual_assert,    clippy::manual_range_contains,    clippy::missing_panics_doc,    clippy::missing_safety_doc,    clippy::must_use_candidate,    clippy::needless_doctest_main,    clippy::needless_lifetimes,    clippy::new_without_default,    clippy::return_self_not_must_use,    clippy::shadow_unrelated,    clippy::trivially_copy_pass_by_ref,    clippy::unnecessary_wraps,    clippy::unused_self,    clippy::used_underscore_binding,    clippy::vec_init_then_push)]#![allow(unknown_lints, mismatched_lifetime_syntaxes)] #[cfg(all(procmacro2_semver_exempt, wrap_proc_macro, not(super_unstable)))]compile_error! {"\    Something is not right. If you've tried to turn on \    procmacro2_semver_exempt, you need to ensure that it \    is turned on for the compilation of the proc-macro2 \    build script as well."} #[cfg(all(    procmacro2_nightly_testing,    feature = "proc-macro",    not(proc_macro_span)))]compile_error! {"\    Build script probe failed to compile."} extern crate alloc; #[cfg(feature = "proc-macro")]extern crate proc_macro; mod marker;mod parse;mod probe;mod rcvec; #[cfg(wrap_proc_macro)]mod detection; // Public for proc_macro2::fallback::force() and unforce(), but those are quite// a niche use case so we omit it from rustdoc.#[doc(hidden)]pub mod fallback; pub mod extra; #[cfg(not(wrap_proc_macro))]use crate::fallback as imp;#[path = "wrapper.rs"]#[cfg(wrap_proc_macro)]mod imp; #[cfg(span_locations)]mod location; use crate::extra::DelimSpan;use crate::marker::{ProcMacroAutoTraits, MARKER};use core::cmp::Ordering;use core::fmt::{self, Debug, Display};use core::hash::{Hash, Hasher};#[cfg(span_locations)]use core::ops::Range;use core::ops::RangeBounds;use core::str::FromStr;use std::error::Error;use std::ffi::CStr;#[cfg(span_locations)]use std::path::PathBuf; #[cfg(span_locations)]#[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))]pub use crate::location::LineColumn; /// An abstract stream of tokens, or more concretely a sequence of token trees.////// This type provides interfaces for iterating over token trees and for/// collecting token trees into one stream.////// Token stream is both the input and output of `#[proc_macro]`,/// `#[proc_macro_attribute]` and `#[proc_macro_derive]` definitions.#[derive(Clone)]pub struct TokenStream {    inner: imp::TokenStream,    _marker: ProcMacroAutoTraits,} /// Error returned from `TokenStream::from_str`.pub struct LexError {    inner: imp::LexError,    _marker: ProcMacroAutoTraits,} impl TokenStream {    fn _new(inner: imp::TokenStream) -> Self {        TokenStream {            inner,            _marker: MARKER,        }    }     fn _new_fallback(inner: fallback::TokenStream) -> Self {        TokenStream {            inner: imp::TokenStream::from(inner),            _marker: MARKER,        }    }     /// Returns an empty `TokenStream` containing no token trees.    pub fn new() -> Self {        TokenStream::_new(imp::TokenStream::new())    }     /// Checks if this `TokenStream` is empty.    pub fn is_empty(&self) -> bool {        self.inner.is_empty()    }} /// `TokenStream::default()` returns an empty stream,/// i.e. this is equivalent with `TokenStream::new()`.impl Default for TokenStream {    fn default() -> Self {        TokenStream::new()    }} /// Attempts to break the string into tokens and parse those tokens into a token/// stream.////// May fail for a number of reasons, for example, if the string contains/// unbalanced delimiters or characters not existing in the language.////// NOTE: Some errors may cause panics instead of returning `LexError`. We/// reserve the right to change these errors into `LexError`s later.impl FromStr for TokenStream {    type Err = LexError;     fn from_str(src: &str) -> Result<TokenStream, LexError> {        match imp::TokenStream::from_str_checked(src) {            Ok(tokens) => Ok(TokenStream::_new(tokens)),            Err(lex) => Err(LexError {                inner: lex,                _marker: MARKER,            }),        }    }} #[cfg(feature = "proc-macro")]#[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))]impl From<proc_macro::TokenStream> for TokenStream {    fn from(inner: proc_macro::TokenStream) -> Self {        TokenStream::_new(imp::TokenStream::from(inner))    }} #[cfg(feature = "proc-macro")]#[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))]impl From<TokenStream> for proc_macro::TokenStream {    fn from(inner: TokenStream) -> Self {        proc_macro::TokenStream::from(inner.inner)    }} impl From<TokenTree> for TokenStream {    fn from(token: TokenTree) -> Self {        TokenStream::_new(imp::TokenStream::from(token))    }} impl Extend<TokenTree> for TokenStream {    fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I) {        self.inner.extend(streams);    }} impl Extend<TokenStream> for TokenStream {    fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {        self.inner            .extend(streams.into_iter().map(|stream| stream.inner));    }} /// Collects a number of token trees into a single stream.impl FromIterator<TokenTree> for TokenStream {    fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {        TokenStream::_new(streams.into_iter().collect())    }}impl FromIterator<TokenStream> for TokenStream {    fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {        TokenStream::_new(streams.into_iter().map(|i| i.inner).collect())    }} /// Prints the token stream as a string that is supposed to be losslessly/// convertible back into the same token stream (modulo spans), except for/// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative/// numeric literals.impl Display for TokenStream {    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {        Display::fmt(&self.inner, f)    }} /// Prints token in a form convenient for debugging.impl Debug for TokenStream {    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {        Debug::fmt(&self.inner, f)    }} impl LexError {    pub fn span(&self) -> Span {        Span::_new(self.inner.span())    }} impl Debug for LexError {    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {        Debug::fmt(&self.inner, f)    }} impl Display for LexError {    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {        Display::fmt(&self.inner, f)    }} impl Error for LexError {} /// A region of source code, along with macro expansion information.#[derive(Copy, Clone)]pub struct Span {    inner: imp::Span,    _marker: ProcMacroAutoTraits,} impl Span {    fn _new(inner: imp::Span) -> Self {        Span {            inner,            _marker: MARKER,        }    }     fn _new_fallback(inner: fallback::Span) -> Self {        Span {            inner: imp::Span::from(inner),            _marker: MARKER,        }    }     /// The span of the invocation of the current procedural macro.    ///    /// Identifiers created with this span will be resolved as if they were    /// written directly at the macro call location (call-site hygiene) and    /// other code at the macro call site will be able to refer to them as well.    pub fn call_site() -> Self {        Span::_new(imp::Span::call_site())    }     /// The span located at the invocation of the procedural macro, but with    /// local variables, labels, and `$crate` resolved at the definition site    /// of the macro. This is the same hygiene behavior as `macro_rules`.    pub fn mixed_site() -> Self {        Span::_new(imp::Span::mixed_site())    }     /// A span that resolves at the macro definition site.    ///    /// This method is semver exempt and not exposed by default.    #[cfg(procmacro2_semver_exempt)]    #[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))]    pub fn def_site() -> Self {        Span::_new(imp::Span::def_site())    }     /// Creates a new span with the same line/column information as `self` but    /// that resolves symbols as though it were at `other`.    pub fn resolved_at(&self, other: Span) -> Span {        Span::_new(self.inner.resolved_at(other.inner))    }     /// Creates a new span with the same name resolution behavior as `self` but    /// with the line/column information of `other`.    pub fn located_at(&self, other: Span) -> Span {        Span::_new(self.inner.located_at(other.inner))    }     /// 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)]    pub fn unstable(self) -> proc_macro::Span {        self.unwrap()    }     /// Returns the span's byte position range in the source file.    ///    /// This method requires the `"span-locations"` feature to be enabled.    ///    /// When executing in a procedural macro context, the returned range is only    /// accurate if compiled with a nightly toolchain. The stable toolchain does    /// not have this information available. When executing outside of a    /// procedural macro, such as main.rs or build.rs, the byte range is always    /// accurate regardless of toolchain.    #[cfg(span_locations)]    #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))]    pub fn byte_range(&self) -> Range<usize> {        self.inner.byte_range()    }     /// Get the starting line/column in the source file for this span.    ///    /// This method requires the `"span-locations"` feature to be enabled.    ///    /// When executing in a procedural macro context, the returned line/column    /// are only meaningful if compiled with a nightly toolchain. The stable    /// toolchain does not have this information available. When executing    /// outside of a procedural macro, such as main.rs or build.rs, the    /// line/column are always meaningful regardless of toolchain.    #[cfg(span_locations)]    #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))]    pub fn start(&self) -> LineColumn {        self.inner.start()    }     /// Get the ending line/column in the source file for this span.    ///    /// This method requires the `"span-locations"` feature to be enabled.    ///    /// When executing in a procedural macro context, the returned line/column    /// are only meaningful if compiled with a nightly toolchain. The stable    /// toolchain does not have this information available. When executing    /// outside of a procedural macro, such as main.rs or build.rs, the    /// line/column are always meaningful regardless of toolchain.    #[cfg(span_locations)]    #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))]    pub fn end(&self) -> LineColumn {        self.inner.end()    }     /// The path to the source file in which this span occurs, for display    /// purposes.    ///    /// This might not correspond to a valid file system path. It might be    /// remapped, or might be an artificial path such as `"<macro expansion>"`.    #[cfg(span_locations)]    #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))]    pub fn file(&self) -> String {        self.inner.file()    }     /// The path to the source file in which this span occurs on disk.    ///    /// This is the actual path on disk. It is unaffected by path remapping.    ///    /// This path should not be embedded in the output of the macro; prefer    /// `file()` instead.    #[cfg(span_locations)]    #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))]    pub fn local_file(&self) -> Option<PathBuf> {        self.inner.local_file()    }     /// Create a new span encompassing `self` and `other`.    ///    /// Returns `None` if `self` and `other` are from different files.

Lines 1–500 of 1355.