#![stable(feature = "proc_macro_lib", since = "1.15.0")]
#![deny(missing_docs)]
#![doc(
html_playground_url = "https://play.rust-lang.org/",
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
test(no_crate_inject, attr(deny(warnings))),
test(attr(allow(dead_code, deprecated, unused_variables, unused_mut)))
)]
#![feature(rustc_allow_const_fn_unstable)]
#![feature(staged_api)]
#![feature(allow_internal_unstable)]
#![feature(decl_macro)]
#![feature(local_key_cell_methods)]
#![feature(maybe_uninit_write_slice)]
#![feature(negative_impls)]
#![feature(new_uninit)]
#![feature(restricted_std)]
#![feature(rustc_attrs)]
#![feature(min_specialization)]
#![feature(strict_provenance)]
#![recursion_limit = "256"]
#[unstable(feature = "proc_macro_internals", issue = "27812")]
#[doc(hidden)]
pub mod bridge;
mod diagnostic;
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
pub use diagnostic::{Diagnostic, Level, MultiSpan};
use std::cmp::Ordering;
use std::ops::{Range, RangeBounds};
use std::path::PathBuf;
use std::str::FromStr;
use std::{error, fmt};
#[stable(feature = "proc_macro_is_available", since = "1.57.0")]
pub fn is_available() -> bool {
bridge::client::is_available()
}
#[rustc_diagnostic_item = "TokenStream"]
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
#[derive(Clone)]
pub struct TokenStream(Option<bridge::client::TokenStream>);
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
impl !Send for TokenStream {}
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
impl !Sync for TokenStream {}
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
#[non_exhaustive]
#[derive(Debug)]
pub struct LexError;
#[stable(feature = "proc_macro_lexerror_impls", since = "1.44.0")]
impl fmt::Display for LexError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("cannot parse string into token stream")
}
}
#[stable(feature = "proc_macro_lexerror_impls", since = "1.44.0")]
impl error::Error for LexError {}
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
impl !Send for LexError {}
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
impl !Sync for LexError {}
#[unstable(feature = "proc_macro_expand", issue = "90765")]
#[non_exhaustive]
#[derive(Debug)]
pub struct ExpandError;
#[unstable(feature = "proc_macro_expand", issue = "90765")]
impl fmt::Display for ExpandError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("macro expansion failed")
}
}
#[unstable(feature = "proc_macro_expand", issue = "90765")]
impl error::Error for ExpandError {}
#[unstable(feature = "proc_macro_expand", issue = "90765")]
impl !Send for ExpandError {}
#[unstable(feature = "proc_macro_expand", issue = "90765")]
impl !Sync for ExpandError {}
impl TokenStream {
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn new() -> TokenStream {
TokenStream(None)
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn is_empty(&self) -> bool {
self.0.as_ref().map(|h| h.is_empty()).unwrap_or(true)
}
#[unstable(feature = "proc_macro_expand", issue = "90765")]
pub fn expand_expr(&self) -> Result<TokenStream, ExpandError> {
let stream = self.0.as_ref().ok_or(ExpandError)?;
match bridge::client::TokenStream::expand_expr(stream) {
Ok(stream) => Ok(TokenStream(Some(stream))),
Err(_) => Err(ExpandError),
}
}
}
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
impl FromStr for TokenStream {
type Err = LexError;
fn from_str(src: &str) -> Result<TokenStream, LexError> {
Ok(TokenStream(Some(bridge::client::TokenStream::from_str(src))))
}
}
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
impl ToString for TokenStream {
fn to_string(&self) -> String {
self.0.as_ref().map(|t| t.to_string()).unwrap_or_default()
}
}
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
impl fmt::Display for TokenStream {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.to_string())
}
}
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
impl fmt::Debug for TokenStream {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("TokenStream ")?;
f.debug_list().entries(self.clone()).finish()
}
}
#[stable(feature = "proc_macro_token_stream_default", since = "1.45.0")]
impl Default for TokenStream {
fn default() -> Self {
TokenStream::new()
}
}
#[unstable(feature = "proc_macro_quote", issue = "54722")]
pub use quote::{quote, quote_span};
fn tree_to_bridge_tree(
tree: TokenTree,
) -> bridge::TokenTree<bridge::client::TokenStream, bridge::client::Span, bridge::client::Symbol> {
match tree {
TokenTree::Group(tt) => bridge::TokenTree::Group(tt.0),
TokenTree::Punct(tt) => bridge::TokenTree::Punct(tt.0),
TokenTree::Ident(tt) => bridge::TokenTree::Ident(tt.0),
TokenTree::Literal(tt) => bridge::TokenTree::Literal(tt.0),
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl From<TokenTree> for TokenStream {
fn from(tree: TokenTree) -> TokenStream {
TokenStream(Some(bridge::client::TokenStream::from_token_tree(tree_to_bridge_tree(tree))))
}
}
struct ConcatTreesHelper {
trees: Vec<
bridge::TokenTree<
bridge::client::TokenStream,
bridge::client::Span,
bridge::client::Symbol,
>,
>,
}
impl ConcatTreesHelper {
fn new(capacity: usize) -> Self {
ConcatTreesHelper { trees: Vec::with_capacity(capacity) }
}
fn push(&mut self, tree: TokenTree) {
self.trees.push(tree_to_bridge_tree(tree));
}
fn build(self) -> TokenStream {
if self.trees.is_empty() {
TokenStream(None)
} else {
TokenStream(Some(bridge::client::TokenStream::concat_trees(None, self.trees)))
}
}
fn append_to(self, stream: &mut TokenStream) {
if self.trees.is_empty() {
return;
}
stream.0 = Some(bridge::client::TokenStream::concat_trees(stream.0.take(), self.trees))
}
}
struct ConcatStreamsHelper {
streams: Vec<bridge::client::TokenStream>,
}
impl ConcatStreamsHelper {
fn new(capacity: usize) -> Self {
ConcatStreamsHelper { streams: Vec::with_capacity(capacity) }
}
fn push(&mut self, stream: TokenStream) {
if let Some(stream) = stream.0 {
self.streams.push(stream);
}
}
fn build(mut self) -> TokenStream {
if self.streams.len() <= 1 {
TokenStream(self.streams.pop())
} else {
TokenStream(Some(bridge::client::TokenStream::concat_streams(None, self.streams)))
}
}
fn append_to(mut self, stream: &mut TokenStream) {
if self.streams.is_empty() {
return;
}
let base = stream.0.take();
if base.is_none() && self.streams.len() == 1 {
stream.0 = self.streams.pop();
} else {
stream.0 = Some(bridge::client::TokenStream::concat_streams(base, self.streams));
}
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl FromIterator<TokenTree> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
let iter = trees.into_iter();
let mut builder = ConcatTreesHelper::new(iter.size_hint().0);
iter.for_each(|tree| builder.push(tree));
builder.build()
}
}
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
impl FromIterator<TokenStream> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
let iter = streams.into_iter();
let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
iter.for_each(|stream| builder.push(stream));
builder.build()
}
}
#[stable(feature = "token_stream_extend", since = "1.30.0")]
impl Extend<TokenTree> for TokenStream {
fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, trees: I) {
let iter = trees.into_iter();
let mut builder = ConcatTreesHelper::new(iter.size_hint().0);
iter.for_each(|tree| builder.push(tree));
builder.append_to(self);
}
}
#[stable(feature = "token_stream_extend", since = "1.30.0")]
impl Extend<TokenStream> for TokenStream {
fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
let iter = streams.into_iter();
let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
iter.for_each(|stream| builder.push(stream));
builder.append_to(self);
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub mod token_stream {
use crate::{bridge, Group, Ident, Literal, Punct, TokenStream, TokenTree};
#[derive(Clone)]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub struct IntoIter(
std::vec::IntoIter<
bridge::TokenTree<
bridge::client::TokenStream,
bridge::client::Span,
bridge::client::Symbol,
>,
>,
);
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl Iterator for IntoIter {
type Item = TokenTree;
fn next(&mut self) -> Option<TokenTree> {
self.0.next().map(|tree| match tree {
bridge::TokenTree::Group(tt) => TokenTree::Group(Group(tt)),
bridge::TokenTree::Punct(tt) => TokenTree::Punct(Punct(tt)),
bridge::TokenTree::Ident(tt) => TokenTree::Ident(Ident(tt)),
bridge::TokenTree::Literal(tt) => TokenTree::Literal(Literal(tt)),
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
fn count(self) -> usize {
self.0.count()
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl IntoIterator for TokenStream {
type Item = TokenTree;
type IntoIter = IntoIter;
fn into_iter(self) -> IntoIter {
IntoIter(self.0.map(|v| v.into_trees()).unwrap_or_default().into_iter())
}
}
}
#[unstable(feature = "proc_macro_quote", issue = "54722")]
#[allow_internal_unstable(proc_macro_def_site, proc_macro_internals)]
#[rustc_builtin_macro]
pub macro quote($($t:tt)*) {
}
#[unstable(feature = "proc_macro_internals", issue = "27812")]
#[doc(hidden)]
mod quote;
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
#[derive(Copy, Clone)]
pub struct Span(bridge::client::Span);
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl !Send for Span {}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl !Sync for Span {}
macro_rules! diagnostic_method {
($name:ident, $level:expr) => {
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
pub fn $name<T: Into<String>>(self, message: T) -> Diagnostic {
Diagnostic::spanned(self, $level, message)
}
};
}
impl Span {
#[unstable(feature = "proc_macro_def_site", issue = "54724")]
pub fn def_site() -> Span {
Span(bridge::client::Span::def_site())
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn call_site() -> Span {
Span(bridge::client::Span::call_site())
}
#[stable(feature = "proc_macro_mixed_site", since = "1.45.0")]
pub fn mixed_site() -> Span {
Span(bridge::client::Span::mixed_site())
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn source_file(&self) -> SourceFile {
SourceFile(self.0.source_file())
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn parent(&self) -> Option<Span> {
self.0.parent().map(Span)
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn source(&self) -> Span {
Span(self.0.source())
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn byte_range(&self) -> Range<usize> {
self.0.byte_range()
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn start(&self) -> LineColumn {
self.0.start().add_1_to_column()
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn end(&self) -> LineColumn {
self.0.end().add_1_to_column()
}
#[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
pub fn before(&self) -> Span {
Span(self.0.before())
}
#[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
pub fn after(&self) -> Span {
Span(self.0.after())
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn join(&self, other: Span) -> Option<Span> {
self.0.join(other.0).map(Span)
}
#[stable(feature = "proc_macro_span_resolved_at", since = "1.45.0")]
pub fn resolved_at(&self, other: Span) -> Span {
Span(self.0.resolved_at(other.0))
}
#[stable(feature = "proc_macro_span_located_at", since = "1.45.0")]
pub fn located_at(&self, other: Span) -> Span {
other.resolved_at(*self)
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn eq(&self, other: &Span) -> bool {
self.0 == other.0
}
#[stable(feature = "proc_macro_source_text", since = "1.66.0")]
pub fn source_text(&self) -> Option<String> {
self.0.source_text()
}
#[doc(hidden)]
#[unstable(feature = "proc_macro_internals", issue = "27812")]
pub fn save_span(&self) -> usize {
self.0.save_span()
}
#[doc(hidden)]
#[unstable(feature = "proc_macro_internals", issue = "27812")]
pub fn recover_proc_macro_span(id: usize) -> Span {
Span(bridge::client::Span::recover_proc_macro_span(id))
}
diagnostic_method!(error, Level::Error);
diagnostic_method!(warning, Level::Warning);
diagnostic_method!(note, Level::Note);
diagnostic_method!(help, Level::Help);
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl fmt::Debug for Span {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct LineColumn {
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub line: usize,
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub column: usize,
}
impl LineColumn {
fn add_1_to_column(self) -> Self {
LineColumn { line: self.line, column: self.column + 1 }
}
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl !Send for LineColumn {}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl !Sync for LineColumn {}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl Ord for LineColumn {
fn cmp(&self, other: &Self) -> Ordering {
self.line.cmp(&other.line).then(self.column.cmp(&other.column))
}
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl PartialOrd for LineColumn {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
#[derive(Clone)]
pub struct SourceFile(bridge::client::SourceFile);
impl SourceFile {
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn path(&self) -> PathBuf {
PathBuf::from(self.0.path())
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn is_real(&self) -> bool {
self.0.is_real()
}
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl fmt::Debug for SourceFile {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SourceFile")
.field("path", &self.path())
.field("is_real", &self.is_real())
.finish()
}
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl PartialEq for SourceFile {
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl Eq for SourceFile {}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
#[derive(Clone)]
pub enum TokenTree {
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
Group(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Group),
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
Ident(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Ident),
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
Punct(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Punct),
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
Literal(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Literal),
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl !Send for TokenTree {}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl !Sync for TokenTree {}
impl TokenTree {
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
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(),
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
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),
}
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl fmt::Debug for TokenTree {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
TokenTree::Group(ref tt) => tt.fmt(f),
TokenTree::Ident(ref tt) => tt.fmt(f),
TokenTree::Punct(ref tt) => tt.fmt(f),
TokenTree::Literal(ref tt) => tt.fmt(f),
}
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl From<Group> for TokenTree {
fn from(g: Group) -> TokenTree {
TokenTree::Group(g)
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl From<Ident> for TokenTree {
fn from(g: Ident) -> TokenTree {
TokenTree::Ident(g)
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl From<Punct> for TokenTree {
fn from(g: Punct) -> TokenTree {
TokenTree::Punct(g)
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl From<Literal> for TokenTree {
fn from(g: Literal) -> TokenTree {
TokenTree::Literal(g)
}
}
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
impl ToString for TokenTree {
fn to_string(&self) -> String {
match *self {
TokenTree::Group(ref t) => t.to_string(),
TokenTree::Ident(ref t) => t.to_string(),
TokenTree::Punct(ref t) => t.to_string(),
TokenTree::Literal(ref t) => t.to_string(),
}
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl fmt::Display for TokenTree {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.to_string())
}
}
#[derive(Clone)]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub struct Group(bridge::Group<bridge::client::TokenStream, bridge::client::Span>);
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl !Send for Group {}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl !Sync for Group {}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub enum Delimiter {
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
Parenthesis,
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
Brace,
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
Bracket,
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
None,
}
impl Group {
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
Group(bridge::Group {
delimiter,
stream: stream.0,
span: bridge::DelimSpan::from_single(Span::call_site().0),
})
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn delimiter(&self) -> Delimiter {
self.0.delimiter
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn stream(&self) -> TokenStream {
TokenStream(self.0.stream.clone())
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn span(&self) -> Span {
Span(self.0.span.entire)
}
#[stable(feature = "proc_macro_group_span", since = "1.55.0")]
pub fn span_open(&self) -> Span {
Span(self.0.span.open)
}
#[stable(feature = "proc_macro_group_span", since = "1.55.0")]
pub fn span_close(&self) -> Span {
Span(self.0.span.close)
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn set_span(&mut self, span: Span) {
self.0.span = bridge::DelimSpan::from_single(span.0);
}
}
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
impl ToString for Group {
fn to_string(&self) -> String {
TokenStream::from(TokenTree::from(self.clone())).to_string()
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl fmt::Display for Group {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.to_string())
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl fmt::Debug for Group {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Group")
.field("delimiter", &self.delimiter())
.field("stream", &self.stream())
.field("span", &self.span())
.finish()
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
#[derive(Clone)]
pub struct Punct(bridge::Punct<bridge::client::Span>);
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl !Send for Punct {}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl !Sync for Punct {}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub enum Spacing {
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
Alone,
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
Joint,
}
impl Punct {
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn new(ch: char, spacing: Spacing) -> Punct {
const LEGAL_CHARS: &[char] = &[
'=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^', '&', '|', '@', '.', ',', ';',
':', '#', '$', '?', '\'',
];
if !LEGAL_CHARS.contains(&ch) {
panic!("unsupported character `{:?}`", ch);
}
Punct(bridge::Punct {
ch: ch as u8,
joint: spacing == Spacing::Joint,
span: Span::call_site().0,
})
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn as_char(&self) -> char {
self.0.ch as char
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn spacing(&self) -> Spacing {
if self.0.joint { Spacing::Joint } else { Spacing::Alone }
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn span(&self) -> Span {
Span(self.0.span)
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn set_span(&mut self, span: Span) {
self.0.span = span.0;
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ToString for Punct {
fn to_string(&self) -> String {
self.as_char().to_string()
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl fmt::Display for Punct {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_char())
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl fmt::Debug for Punct {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Punct")
.field("ch", &self.as_char())
.field("spacing", &self.spacing())
.field("span", &self.span())
.finish()
}
}
#[stable(feature = "proc_macro_punct_eq", since = "1.50.0")]
impl PartialEq<char> for Punct {
fn eq(&self, rhs: &char) -> bool {
self.as_char() == *rhs
}
}
#[stable(feature = "proc_macro_punct_eq_flipped", since = "1.52.0")]
impl PartialEq<Punct> for char {
fn eq(&self, rhs: &Punct) -> bool {
*self == rhs.as_char()
}
}
#[derive(Clone)]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub struct Ident(bridge::Ident<bridge::client::Span, bridge::client::Symbol>);
impl Ident {
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn new(string: &str, span: Span) -> Ident {
Ident(bridge::Ident {
sym: bridge::client::Symbol::new_ident(string, false),
is_raw: false,
span: span.0,
})
}
#[stable(feature = "proc_macro_raw_ident", since = "1.47.0")]
pub fn new_raw(string: &str, span: Span) -> Ident {
Ident(bridge::Ident {
sym: bridge::client::Symbol::new_ident(string, true),
is_raw: true,
span: span.0,
})
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn span(&self) -> Span {
Span(self.0.span)
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn set_span(&mut self, span: Span) {
self.0.span = span.0;
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ToString for Ident {
fn to_string(&self) -> String {
self.0.sym.with(|sym| if self.0.is_raw { ["r#", sym].concat() } else { sym.to_owned() })
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl fmt::Display for Ident {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.0.is_raw {
f.write_str("r#")?;
}
fmt::Display::fmt(&self.0.sym, f)
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl fmt::Debug for Ident {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Ident")
.field("ident", &self.to_string())
.field("span", &self.span())
.finish()
}
}
#[derive(Clone)]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub struct Literal(bridge::Literal<bridge::client::Span, bridge::client::Symbol>);
macro_rules! suffixed_int_literals {
($($name:ident => $kind:ident,)*) => ($(
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn $name(n: $kind) -> Literal {
Literal(bridge::Literal {
kind: bridge::LitKind::Integer,
symbol: bridge::client::Symbol::new(&n.to_string()),
suffix: Some(bridge::client::Symbol::new(stringify!($kind))),
span: Span::call_site().0,
})
}
)*)
}
macro_rules! unsuffixed_int_literals {
($($name:ident => $kind:ident,)*) => ($(
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn $name(n: $kind) -> Literal {
Literal(bridge::Literal {
kind: bridge::LitKind::Integer,
symbol: bridge::client::Symbol::new(&n.to_string()),
suffix: None,
span: Span::call_site().0,
})
}
)*)
}
impl Literal {
fn new(kind: bridge::LitKind, value: &str, suffix: Option<&str>) -> Self {
Literal(bridge::Literal {
kind,
symbol: bridge::client::Symbol::new(value),
suffix: suffix.map(bridge::client::Symbol::new),
span: Span::call_site().0,
})
}
suffixed_int_literals! {
u8_suffixed => u8,
u16_suffixed => u16,
u32_suffixed => u32,
u64_suffixed => u64,
u128_suffixed => u128,
usize_suffixed => usize,
i8_suffixed => i8,
i16_suffixed => i16,
i32_suffixed => i32,
i64_suffixed => i64,
i128_suffixed => i128,
isize_suffixed => isize,
}
unsuffixed_int_literals! {
u8_unsuffixed => u8,
u16_unsuffixed => u16,
u32_unsuffixed => u32,
u64_unsuffixed => u64,
u128_unsuffixed => u128,
usize_unsuffixed => usize,
i8_unsuffixed => i8,
i16_unsuffixed => i16,
i32_unsuffixed => i32,
i64_unsuffixed => i64,
i128_unsuffixed => i128,
isize_unsuffixed => isize,
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn f32_unsuffixed(n: f32) -> Literal {
if !n.is_finite() {
panic!("Invalid float literal {n}");
}
let mut repr = n.to_string();
if !repr.contains('.') {
repr.push_str(".0");
}
Literal::new(bridge::LitKind::Float, &repr, None)
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn f32_suffixed(n: f32) -> Literal {
if !n.is_finite() {
panic!("Invalid float literal {n}");
}
Literal::new(bridge::LitKind::Float, &n.to_string(), Some("f32"))
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn f64_unsuffixed(n: f64) -> Literal {
if !n.is_finite() {
panic!("Invalid float literal {n}");
}
let mut repr = n.to_string();
if !repr.contains('.') {
repr.push_str(".0");
}
Literal::new(bridge::LitKind::Float, &repr, None)
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn f64_suffixed(n: f64) -> Literal {
if !n.is_finite() {
panic!("Invalid float literal {n}");
}
Literal::new(bridge::LitKind::Float, &n.to_string(), Some("f64"))
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn string(string: &str) -> Literal {
let quoted = format!("{:?}", string);
assert!(quoted.starts_with('"') && quoted.ends_with('"'));
let symbol = "ed[1..quoted.len() - 1];
Literal::new(bridge::LitKind::Str, symbol, None)
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn character(ch: char) -> Literal {
let quoted = format!("{:?}", ch);
assert!(quoted.starts_with('\'') && quoted.ends_with('\''));
let symbol = "ed[1..quoted.len() - 1];
Literal::new(bridge::LitKind::Char, symbol, None)
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn byte_string(bytes: &[u8]) -> Literal {
let string = bytes.escape_ascii().to_string();
Literal::new(bridge::LitKind::ByteStr, &string, None)
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn span(&self) -> Span {
Span(self.0.span)
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn set_span(&mut self, span: Span) {
self.0.span = span.0;
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
self.0.span.subspan(range.start_bound().cloned(), range.end_bound().cloned()).map(Span)
}
fn with_symbol_and_suffix<R>(&self, f: impl FnOnce(&str, &str) -> R) -> R {
self.0.symbol.with(|symbol| match self.0.suffix {
Some(suffix) => suffix.with(|suffix| f(symbol, suffix)),
None => f(symbol, ""),
})
}
fn with_stringify_parts<R>(&self, f: impl FnOnce(&[&str]) -> R) -> R {
fn get_hashes_str(num: u8) -> &'static str {
const HASHES: &str = "\
################################################################\
################################################################\
################################################################\
################################################################\
";
const _: () = assert!(HASHES.len() == 256);
&HASHES[..num as usize]
}
self.with_symbol_and_suffix(|symbol, suffix| match self.0.kind {
bridge::LitKind::Byte => f(&["b'", symbol, "'", suffix]),
bridge::LitKind::Char => f(&["'", symbol, "'", suffix]),
bridge::LitKind::Str => f(&["\"", symbol, "\"", suffix]),
bridge::LitKind::StrRaw(n) => {
let hashes = get_hashes_str(n);
f(&["r", hashes, "\"", symbol, "\"", hashes, suffix])
}
bridge::LitKind::ByteStr => f(&["b\"", symbol, "\"", suffix]),
bridge::LitKind::ByteStrRaw(n) => {
let hashes = get_hashes_str(n);
f(&["br", hashes, "\"", symbol, "\"", hashes, suffix])
}
_ => f(&[symbol, suffix]),
})
}
}
#[stable(feature = "proc_macro_literal_parse", since = "1.54.0")]
impl FromStr for Literal {
type Err = LexError;
fn from_str(src: &str) -> Result<Self, LexError> {
match bridge::client::FreeFunctions::literal_from_str(src) {
Ok(literal) => Ok(Literal(literal)),
Err(()) => Err(LexError),
}
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ToString for Literal {
fn to_string(&self) -> String {
self.with_stringify_parts(|parts| parts.concat())
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl fmt::Display for Literal {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.with_stringify_parts(|parts| {
for part in parts {
fmt::Display::fmt(part, f)?;
}
Ok(())
})
}
}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl fmt::Debug for Literal {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Literal")
.field("kind", &format_args!("{:?}", &self.0.kind))
.field("symbol", &self.0.symbol)
.field("suffix", &format_args!("{:?}", &self.0.suffix))
.field("span", &self.0.span)
.finish()
}
}
#[unstable(feature = "proc_macro_tracked_env", issue = "99515")]
pub mod tracked_env {
use std::env::{self, VarError};
use std::ffi::OsStr;
#[unstable(feature = "proc_macro_tracked_env", issue = "99515")]
pub fn var<K: AsRef<OsStr> + AsRef<str>>(key: K) -> Result<String, VarError> {
let key: &str = key.as_ref();
let value = env::var(key);
crate::bridge::client::FreeFunctions::track_env_var(key, value.as_deref().ok());
value
}
}
#[unstable(feature = "track_path", issue = "99515")]
pub mod tracked_path {
#[unstable(feature = "track_path", issue = "99515")]
pub fn path<P: AsRef<str>>(path: P) {
let path: &str = path.as_ref();
crate::bridge::client::FreeFunctions::track_path(path);
}
}