cloud-hypervisor/vendor/registry-40351f815f426200/proc-macro2/src/lib.rs
Samuel Ortiz d5f5648b37 vendor: Add vendored dependencies
We use cargo vendor to generate a .cargo/config file and the vendor
directory. Vendoring allows us to lock our dependencies and to modify
them easily from the top level Cargo.toml.

We vendor all dependencies, including the crates.io ones, which allows
for network isolated builds.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2019-06-04 17:51:52 +02:00

1157 lines
36 KiB
Rust

//! A wrapper around the procedural macro API of the compiler's [`proc_macro`]
//! crate. This library serves three purposes:
//!
//! [`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;
//!
//! # 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
//! ```
//!
//! 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.
// Proc-macro2 types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/proc-macro2/0.4.30")]
#![cfg_attr(any(proc_macro_span, super_unstable), 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;
extern crate unicode_xid;
use std::cmp::Ordering;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use std::marker;
#[cfg(procmacro2_semver_exempt)]
use std::path::PathBuf;
use std::rc::Rc;
use std::str::FromStr;
#[macro_use]
mod strnom;
mod fallback;
#[cfg(not(wrap_proc_macro))]
use fallback as imp;
#[path = "wrapper.rs"]
#[cfg(wrap_proc_macro)]
mod imp;
/// 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: marker::PhantomData<Rc<()>>,
}
/// Error returned from `TokenStream::from_str`.
pub struct LexError {
inner: imp::LexError,
_marker: marker::PhantomData<Rc<()>>,
}
impl TokenStream {
fn _new(inner: imp::TokenStream) -> TokenStream {
TokenStream {
inner: inner,
_marker: marker::PhantomData,
}
}
fn _new_stable(inner: fallback::TokenStream) -> TokenStream {
TokenStream {
inner: inner.into(),
_marker: marker::PhantomData,
}
}
/// Returns an empty `TokenStream` containing no token trees.
pub fn new() -> TokenStream {
TokenStream::_new(imp::TokenStream::new())
}
#[deprecated(since = "0.4.4", note = "please use TokenStream::new")]
pub fn empty() -> TokenStream {
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> {
let e = src.parse().map_err(|e| LexError {
inner: e,
_marker: marker::PhantomData,
})?;
Ok(TokenStream::_new(e))
}
}
#[cfg(use_proc_macro)]
impl From<proc_macro::TokenStream> for TokenStream {
fn from(inner: proc_macro::TokenStream) -> TokenStream {
TokenStream::_new(inner.into())
}
}
#[cfg(use_proc_macro)]
impl From<TokenStream> for proc_macro::TokenStream {
fn from(inner: TokenStream) -> proc_macro::TokenStream {
inner.inner.into()
}
}
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 fmt::Display for TokenStream {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
/// Prints token in a form convenient for debugging.
impl fmt::Debug for TokenStream {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
impl fmt::Debug for LexError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
/// The source file of a given `Span`.
///
/// This type is semver exempt and not exposed by default.
#[cfg(procmacro2_semver_exempt)]
#[derive(Clone, PartialEq, Eq)]
pub struct SourceFile {
inner: imp::SourceFile,
_marker: marker::PhantomData<Rc<()>>,
}
#[cfg(procmacro2_semver_exempt)]
impl SourceFile {
fn _new(inner: imp::SourceFile) -> Self {
SourceFile {
inner: inner,
_marker: marker::PhantomData,
}
}
/// Get the path to this source file.
///
/// ### Note
///
/// If the code span associated with this `SourceFile` was generated by an
/// external macro, this may not be an actual path on the filesystem. Use
/// [`is_real`] to check.
///
/// Also note that even if `is_real` returns `true`, if
/// `--remap-path-prefix` was passed on the command line, the path as given
/// may not actually be valid.
///
/// [`is_real`]: #method.is_real
pub fn path(&self) -> PathBuf {
self.inner.path()
}
/// Returns `true` if this source file is a real source file, and not
/// generated by an external macro's expansion.
pub fn is_real(&self) -> bool {
self.inner.is_real()
}
}
#[cfg(procmacro2_semver_exempt)]
impl fmt::Debug for SourceFile {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
/// A line-column pair representing the start or end of a `Span`.
///
/// This type is semver exempt and not exposed by default.
#[cfg(span_locations)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct LineColumn {
/// The 1-indexed line in the source file on which the span starts or ends
/// (inclusive).
pub line: usize,
/// The 0-indexed column (in UTF-8 characters) in the source file on which
/// the span starts or ends (inclusive).
pub column: usize,
}
/// A region of source code, along with macro expansion information.
#[derive(Copy, Clone)]
pub struct Span {
inner: imp::Span,
_marker: marker::PhantomData<Rc<()>>,
}
impl Span {
fn _new(inner: imp::Span) -> Span {
Span {
inner: inner,
_marker: marker::PhantomData,
}
}
fn _new_stable(inner: fallback::Span) -> Span {
Span {
inner: inner.into(),
_marker: marker::PhantomData,
}
}
/// 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() -> Span {
Span::_new(imp::Span::call_site())
}
/// A span that resolves at the macro definition site.
///
/// This method is semver exempt and not exposed by default.
#[cfg(procmacro2_semver_exempt)]
pub fn def_site() -> Span {
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`.
///
/// This method is semver exempt and not exposed by default.
#[cfg(procmacro2_semver_exempt)]
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`.
///
/// This method is semver exempt and not exposed by default.
#[cfg(procmacro2_semver_exempt)]
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()
}
/// The original source file into which this span points.
///
/// This method is semver exempt and not exposed by default.
#[cfg(procmacro2_semver_exempt)]
pub fn source_file(&self) -> SourceFile {
SourceFile::_new(self.inner.source_file())
}
/// Get the starting line/column in the source file for this span.
///
/// 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 {
line: line,
column: column,
}
}
/// Get the ending line/column in the source file for this span.
///
/// 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 {
line: line,
column: column,
}
}
/// Create a new span encompassing `self` and `other`.
///
/// Returns `None` if `self` and `other` are from different files.
///
/// This method is semver exempt and not exposed by default.
#[cfg(procmacro2_semver_exempt)]
pub fn join(&self, other: Span) -> Option<Span> {
self.inner.join(other.inner).map(Span::_new)
}
/// Compares to spans to see if they're equal.
///
/// This method is semver exempt and not exposed by default.
#[cfg(procmacro2_semver_exempt)]
pub fn eq(&self, other: &Span) -> bool {
self.inner.eq(&other.inner)
}
}
/// Prints a span in a form convenient for debugging.
impl fmt::Debug for Span {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
/// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`).
#[derive(Clone)]
pub enum TokenTree {
/// A token stream surrounded by bracket delimiters.
Group(Group),
/// An identifier.
Ident(Ident),
/// A single punctuation character (`+`, `,`, `$`, etc.).
Punct(Punct),
/// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc.
Literal(Literal),
}
impl TokenTree {
/// Returns the span of this tree, delegating to the `span` method of
/// the contained token or a delimited stream.
pub fn span(&self) -> Span {
match *self {
TokenTree::Group(ref t) => t.span(),
TokenTree::Ident(ref t) => t.span(),
TokenTree::Punct(ref t) => t.span(),
TokenTree::Literal(ref t) => t.span(),
}
}
/// Configures the span for *only this token*.
///
/// Note that if this token is a `Group` then this method will not configure
/// the span of each of the internal tokens, this will simply delegate to
/// the `set_span` method of each variant.
pub fn set_span(&mut self, span: Span) {
match *self {
TokenTree::Group(ref mut t) => t.set_span(span),
TokenTree::Ident(ref mut t) => t.set_span(span),
TokenTree::Punct(ref mut t) => t.set_span(span),
TokenTree::Literal(ref mut t) => t.set_span(span),
}
}
}
impl From<Group> for TokenTree {
fn from(g: Group) -> TokenTree {
TokenTree::Group(g)
}
}
impl From<Ident> for TokenTree {
fn from(g: Ident) -> TokenTree {
TokenTree::Ident(g)
}
}
impl From<Punct> for TokenTree {
fn from(g: Punct) -> TokenTree {
TokenTree::Punct(g)
}
}
impl From<Literal> for TokenTree {
fn from(g: Literal) -> TokenTree {
TokenTree::Literal(g)
}
}
/// Prints the token tree as a string that is supposed to be losslessly
/// convertible back into the same token tree (modulo spans), except for
/// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative
/// numeric literals.
impl fmt::Display for TokenTree {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TokenTree::Group(ref t) => t.fmt(f),
TokenTree::Ident(ref t) => t.fmt(f),
TokenTree::Punct(ref t) => t.fmt(f),
TokenTree::Literal(ref t) => t.fmt(f),
}
}
}
/// Prints token tree in a form convenient for debugging.
impl fmt::Debug for TokenTree {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Each of these has the name in the struct type in the derived debug,
// so don't bother with an extra layer of indirection
match *self {
TokenTree::Group(ref t) => t.fmt(f),
TokenTree::Ident(ref t) => {
let mut debug = f.debug_struct("Ident");
debug.field("sym", &format_args!("{}", t));
imp::debug_span_field_if_nontrivial(&mut debug, t.span().inner);
debug.finish()
}
TokenTree::Punct(ref t) => t.fmt(f),
TokenTree::Literal(ref t) => t.fmt(f),
}
}
}
/// A delimited token stream.
///
/// A `Group` internally contains a `TokenStream` which is surrounded by
/// `Delimiter`s.
#[derive(Clone)]
pub struct Group {
inner: imp::Group,
}
/// Describes how a sequence of token trees is delimited.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Delimiter {
/// `( ... )`
Parenthesis,
/// `{ ... }`
Brace,
/// `[ ... ]`
Bracket,
/// `Ø ... Ø`
///
/// An implicit delimiter, that may, for example, appear around tokens
/// coming from a "macro variable" `$var`. It is important to preserve
/// operator priorities in cases like `$var * 3` where `$var` is `1 + 2`.
/// Implicit delimiters may not survive roundtrip of a token stream through
/// a string.
None,
}
impl Group {
fn _new(inner: imp::Group) -> Self {
Group { inner: inner }
}
fn _new_stable(inner: fallback::Group) -> Self {
Group {
inner: inner.into(),
}
}
/// Creates a new `Group` with the given delimiter and token stream.
///
/// This constructor will set the span for this group to
/// `Span::call_site()`. To change the span you can use the `set_span`
/// method below.
pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
Group {
inner: imp::Group::new(delimiter, stream.inner),
}
}
/// Returns the delimiter of this `Group`
pub fn delimiter(&self) -> Delimiter {
self.inner.delimiter()
}
/// Returns the `TokenStream` of tokens that are delimited in this `Group`.
///
/// Note that the returned token stream does not include the delimiter
/// returned above.
pub fn stream(&self) -> TokenStream {
TokenStream::_new(self.inner.stream())
}
/// Returns the span for the delimiters of this token stream, spanning the
/// entire `Group`.
///
/// ```text
/// pub fn span(&self) -> Span {
/// ^^^^^^^
/// ```
pub fn span(&self) -> Span {
Span::_new(self.inner.span())
}
/// Returns the span pointing to the opening delimiter of this group.
///
/// ```text
/// pub fn span_open(&self) -> Span {
/// ^
/// ```
#[cfg(procmacro2_semver_exempt)]
pub fn span_open(&self) -> Span {
Span::_new(self.inner.span_open())
}
/// Returns the span pointing to the closing delimiter of this group.
///
/// ```text
/// pub fn span_close(&self) -> Span {
/// ^
/// ```
#[cfg(procmacro2_semver_exempt)]
pub fn span_close(&self) -> Span {
Span::_new(self.inner.span_close())
}
/// Configures the span for this `Group`'s delimiters, but not its internal
/// tokens.
///
/// This method will **not** set the span of all the internal tokens spanned
/// by this group, but rather it will only set the span of the delimiter
/// tokens at the level of the `Group`.
pub fn set_span(&mut self, span: Span) {
self.inner.set_span(span.inner)
}
}
/// Prints the group as a string that should be losslessly convertible back
/// into the same group (modulo spans), except for possibly `TokenTree::Group`s
/// with `Delimiter::None` delimiters.
impl fmt::Display for Group {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.inner, formatter)
}
}
impl fmt::Debug for Group {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&self.inner, formatter)
}
}
/// An `Punct` is an single punctuation character like `+`, `-` or `#`.
///
/// Multicharacter operators like `+=` are represented as two instances of
/// `Punct` with different forms of `Spacing` returned.
#[derive(Clone)]
pub struct Punct {
op: char,
spacing: Spacing,
span: Span,
}
/// Whether an `Punct` is followed immediately by another `Punct` or followed by
/// another token or whitespace.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Spacing {
/// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`.
Alone,
/// E.g. `+` is `Joint` in `+=` or `'#`.
///
/// Additionally, single quote `'` can join with identifiers to form
/// lifetimes `'ident`.
Joint,
}
impl Punct {
/// Creates a new `Punct` from the given character and spacing.
///
/// The `ch` argument must be a valid punctuation character permitted by the
/// language, otherwise the function will panic.
///
/// The returned `Punct` will have the default span of `Span::call_site()`
/// which can be further configured with the `set_span` method below.
pub fn new(op: char, spacing: Spacing) -> Punct {
Punct {
op: op,
spacing: spacing,
span: Span::call_site(),
}
}
/// Returns the value of this punctuation character as `char`.
pub fn as_char(&self) -> char {
self.op
}
/// Returns the spacing of this punctuation character, indicating whether
/// it's immediately followed by another `Punct` in the token stream, so
/// they can potentially be combined into a multicharacter operator
/// (`Joint`), or it's followed by some other token or whitespace (`Alone`)
/// so the operator has certainly ended.
pub fn spacing(&self) -> Spacing {
self.spacing
}
/// Returns the span for this punctuation character.
pub fn span(&self) -> Span {
self.span
}
/// Configure the span for this punctuation character.
pub fn set_span(&mut self, span: Span) {
self.span = span;
}
}
/// Prints the punctuation character as a string that should be losslessly
/// convertible back into the same character.
impl fmt::Display for Punct {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.op.fmt(f)
}
}
impl fmt::Debug for Punct {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let mut debug = fmt.debug_struct("Punct");
debug.field("op", &self.op);
debug.field("spacing", &self.spacing);
imp::debug_span_field_if_nontrivial(&mut debug, self.span.inner);
debug.finish()
}
}
/// A word of Rust code, which may be a keyword or legal variable name.
///
/// An identifier consists of at least one Unicode code point, the first of
/// which has the XID_Start property and the rest of which have the XID_Continue
/// property.
///
/// - The empty string is not an identifier. Use `Option<Ident>`.
/// - A lifetime is not an identifier. Use `syn::Lifetime` instead.
///
/// An identifier constructed with `Ident::new` is permitted to be a Rust
/// keyword, though parsing one through its [`Parse`] implementation rejects
/// Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the
/// behaviour of `Ident::new`.
///
/// [`Parse`]: https://docs.rs/syn/0.15/syn/parse/trait.Parse.html
///
/// # Examples
///
/// A new ident can be created from a string using the `Ident::new` function.
/// A span must be provided explicitly which governs the name resolution
/// behavior of the resulting identifier.
///
/// ```edition2018
/// use proc_macro2::{Ident, Span};
///
/// fn main() {
/// let call_ident = Ident::new("calligraphy", Span::call_site());
///
/// println!("{}", call_ident);
/// }
/// ```
///
/// An ident can be interpolated into a token stream using the `quote!` macro.
///
/// ```edition2018
/// use proc_macro2::{Ident, Span};
/// use quote::quote;
///
/// fn main() {
/// let ident = Ident::new("demo", Span::call_site());
///
/// // Create a variable binding whose name is this ident.
/// let expanded = quote! { let #ident = 10; };
///
/// // Create a variable binding with a slightly different name.
/// let temp_ident = Ident::new(&format!("new_{}", ident), Span::call_site());
/// let expanded = quote! { let #temp_ident = 10; };
/// }
/// ```
///
/// A string representation of the ident is available through the `to_string()`
/// method.
///
/// ```edition2018
/// # use proc_macro2::{Ident, Span};
/// #
/// # let ident = Ident::new("another_identifier", Span::call_site());
/// #
/// // Examine the ident as a string.
/// let ident_string = ident.to_string();
/// if ident_string.len() > 60 {
/// println!("Very long identifier: {}", ident_string)
/// }
/// ```
#[derive(Clone)]
pub struct Ident {
inner: imp::Ident,
_marker: marker::PhantomData<Rc<()>>,
}
impl Ident {
fn _new(inner: imp::Ident) -> Ident {
Ident {
inner: inner,
_marker: marker::PhantomData,
}
}
/// Creates a new `Ident` with the given `string` as well as the specified
/// `span`.
///
/// The `string` argument must be a valid identifier permitted by the
/// language, otherwise the function will panic.
///
/// Note that `span`, currently in rustc, configures the hygiene information
/// for this identifier.
///
/// As of this time `Span::call_site()` explicitly opts-in to "call-site"
/// hygiene meaning that identifiers created with this span will be resolved
/// as if they were written directly at the location of the macro call, and
/// other code at the macro call site will be able to refer to them as well.
///
/// Later spans like `Span::def_site()` will allow to opt-in to
/// "definition-site" hygiene meaning that identifiers created with this
/// span will be resolved at the location of the macro definition and other
/// code at the macro call site will not be able to refer to them.
///
/// Due to the current importance of hygiene this constructor, unlike other
/// tokens, requires a `Span` to be specified at construction.
///
/// # Panics
///
/// Panics if the input string is neither a keyword nor a legal variable
/// name. If you are not sure whether the string contains an identifier and
/// need to handle an error case, use
/// <a href="https://docs.rs/syn/0.15/syn/fn.parse_str.html"><code
/// style="padding-right:0;">syn::parse_str</code></a><code
/// style="padding-left:0;">::&lt;Ident&gt;</code>
/// rather than `Ident::new`.
pub fn new(string: &str, span: Span) -> Ident {
Ident::_new(imp::Ident::new(string, span.inner))
}
/// Same as `Ident::new`, but creates a raw identifier (`r#ident`).
///
/// This method is semver exempt and not exposed by default.
#[cfg(procmacro2_semver_exempt)]
pub fn new_raw(string: &str, span: Span) -> Ident {
Ident::_new_raw(string, span)
}
fn _new_raw(string: &str, span: Span) -> Ident {
Ident::_new(imp::Ident::new_raw(string, span.inner))
}
/// Returns the span of this `Ident`.
pub fn span(&self) -> Span {
Span::_new(self.inner.span())
}
/// Configures the span of this `Ident`, possibly changing its hygiene
/// context.
pub fn set_span(&mut self, span: Span) {
self.inner.set_span(span.inner);
}
}
impl PartialEq for Ident {
fn eq(&self, other: &Ident) -> bool {
self.inner == other.inner
}
}
impl<T> PartialEq<T> for Ident
where
T: ?Sized + AsRef<str>,
{
fn eq(&self, other: &T) -> bool {
self.inner == other
}
}
impl Eq for Ident {}
impl PartialOrd for Ident {
fn partial_cmp(&self, other: &Ident) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Ident {
fn cmp(&self, other: &Ident) -> Ordering {
self.to_string().cmp(&other.to_string())
}
}
impl Hash for Ident {
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.to_string().hash(hasher)
}
}
/// Prints the identifier as a string that should be losslessly convertible back
/// into the same identifier.
impl fmt::Display for Ident {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
impl fmt::Debug for Ident {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
/// A literal string (`"hello"`), byte string (`b"hello"`), character (`'a'`),
/// byte character (`b'a'`), an integer or floating point number with or without
/// a suffix (`1`, `1u8`, `2.3`, `2.3f32`).
///
/// Boolean literals like `true` and `false` do not belong here, they are
/// `Ident`s.
#[derive(Clone)]
pub struct Literal {
inner: imp::Literal,
_marker: marker::PhantomData<Rc<()>>,
}
macro_rules! suffixed_int_literals {
($($name:ident => $kind:ident,)*) => ($(
/// Creates a new suffixed integer literal with the specified value.
///
/// This function will create an integer like `1u32` where the integer
/// value specified is the first part of the token and the integral is
/// also suffixed at the end. Literals created from negative numbers may
/// not survive rountrips through `TokenStream` or strings and may be
/// broken into two tokens (`-` and positive literal).
///
/// Literals created through this method have the `Span::call_site()`
/// span by default, which can be configured with the `set_span` method
/// below.
pub fn $name(n: $kind) -> Literal {
Literal::_new(imp::Literal::$name(n))
}
)*)
}
macro_rules! unsuffixed_int_literals {
($($name:ident => $kind:ident,)*) => ($(
/// Creates a new unsuffixed integer literal with the specified value.
///
/// This function will create an integer like `1` where the integer
/// value specified is the first part of the token. No suffix is
/// specified on this token, meaning that invocations like
/// `Literal::i8_unsuffixed(1)` are equivalent to
/// `Literal::u32_unsuffixed(1)`. Literals created from negative numbers
/// may not survive rountrips through `TokenStream` or strings and may
/// be broken into two tokens (`-` and positive literal).
///
/// Literals created through this method have the `Span::call_site()`
/// span by default, which can be configured with the `set_span` method
/// below.
pub fn $name(n: $kind) -> Literal {
Literal::_new(imp::Literal::$name(n))
}
)*)
}
impl Literal {
fn _new(inner: imp::Literal) -> Literal {
Literal {
inner: inner,
_marker: marker::PhantomData,
}
}
fn _new_stable(inner: fallback::Literal) -> Literal {
Literal {
inner: inner.into(),
_marker: marker::PhantomData,
}
}
suffixed_int_literals! {
u8_suffixed => u8,
u16_suffixed => u16,
u32_suffixed => u32,
u64_suffixed => u64,
usize_suffixed => usize,
i8_suffixed => i8,
i16_suffixed => i16,
i32_suffixed => i32,
i64_suffixed => i64,
isize_suffixed => isize,
}
#[cfg(u128)]
suffixed_int_literals! {
u128_suffixed => u128,
i128_suffixed => i128,
}
unsuffixed_int_literals! {
u8_unsuffixed => u8,
u16_unsuffixed => u16,
u32_unsuffixed => u32,
u64_unsuffixed => u64,
usize_unsuffixed => usize,
i8_unsuffixed => i8,
i16_unsuffixed => i16,
i32_unsuffixed => i32,
i64_unsuffixed => i64,
isize_unsuffixed => isize,
}
#[cfg(u128)]
unsuffixed_int_literals! {
u128_unsuffixed => u128,
i128_unsuffixed => i128,
}
pub fn f64_unsuffixed(f: f64) -> Literal {
assert!(f.is_finite());
Literal::_new(imp::Literal::f64_unsuffixed(f))
}
pub fn f64_suffixed(f: f64) -> Literal {
assert!(f.is_finite());
Literal::_new(imp::Literal::f64_suffixed(f))
}
/// Creates a new unsuffixed floating-point literal.
///
/// This constructor is similar to those like `Literal::i8_unsuffixed` where
/// the float's value is emitted directly into the token but no suffix is
/// used, so it may be inferred to be a `f64` later in the compiler.
/// Literals created from negative numbers may not survive rountrips through
/// `TokenStream` or strings and may be broken into two tokens (`-` and
/// positive literal).
///
/// # Panics
///
/// This function requires that the specified float is finite, for example
/// if it is infinity or NaN this function will panic.
pub fn f32_unsuffixed(f: f32) -> Literal {
assert!(f.is_finite());
Literal::_new(imp::Literal::f32_unsuffixed(f))
}
pub fn f32_suffixed(f: f32) -> Literal {
assert!(f.is_finite());
Literal::_new(imp::Literal::f32_suffixed(f))
}
pub fn string(string: &str) -> Literal {
Literal::_new(imp::Literal::string(string))
}
pub fn character(ch: char) -> Literal {
Literal::_new(imp::Literal::character(ch))
}
pub fn byte_string(s: &[u8]) -> Literal {
Literal::_new(imp::Literal::byte_string(s))
}
pub fn span(&self) -> Span {
Span::_new(self.inner.span())
}
pub fn set_span(&mut self, span: Span) {
self.inner.set_span(span.inner);
}
}
impl fmt::Debug for Literal {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
impl fmt::Display for Literal {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
/// Public implementation details for the `TokenStream` type, such as iterators.
pub mod token_stream {
use std::fmt;
use std::marker;
use std::rc::Rc;
use imp;
pub use TokenStream;
use TokenTree;
/// An iterator over `TokenStream`'s `TokenTree`s.
///
/// The iteration is "shallow", e.g. the iterator doesn't recurse into
/// delimited groups, and returns whole groups as token trees.
#[derive(Clone)]
pub struct IntoIter {
inner: imp::TokenTreeIter,
_marker: marker::PhantomData<Rc<()>>,
}
impl Iterator for IntoIter {
type Item = TokenTree;
fn next(&mut self) -> Option<TokenTree> {
self.inner.next()
}
}
impl fmt::Debug for IntoIter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
impl IntoIterator for TokenStream {
type Item = TokenTree;
type IntoIter = IntoIter;
fn into_iter(self) -> IntoIter {
IntoIter {
inner: self.inner.into_iter(),
_marker: marker::PhantomData,
}
}
}
}