Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: proc-macro2: import crate

This is a subset of the Rust `proc-macro2` crate, version 1.0.101
(released 2025-08-16), licensed under "Apache-2.0 OR MIT", from:

https://github.com/dtolnay/proc-macro2/raw/1.0.101/src

The files are copied as-is, with no modifications whatsoever (not even
adding the SPDX identifiers).

For copyright details, please see:

https://github.com/dtolnay/proc-macro2/blob/1.0.101/README.md#license
https://github.com/dtolnay/proc-macro2/blob/1.0.101/LICENSE-APACHE
https://github.com/dtolnay/proc-macro2/blob/1.0.101/LICENSE-MIT

The next two patches modify these files as needed for use within the
kernel. This patch split allows reviewers to double-check the import
and to clearly see the differences introduced.

The following script may be used to verify the contents:

for path in $(cd rust/proc-macro2/ && find . -type f -name '*.rs'); do
curl --silent --show-error --location \
https://github.com/dtolnay/proc-macro2/raw/1.0.101/src/$path \
| diff --unified rust/proc-macro2/$path - && echo $path: OK
done

Reviewed-by: Gary Guo <gary@garyguo.net>
Tested-by: Gary Guo <gary@garyguo.net>
Tested-by: Jesung Yang <y.j3ms.n@gmail.com>
Link: https://patch.msgid.link/20251124151837.2184382-7-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

+5098
+75
rust/proc-macro2/detection.rs
··· 1 + use core::sync::atomic::{AtomicUsize, Ordering}; 2 + use std::sync::Once; 3 + 4 + static WORKS: AtomicUsize = AtomicUsize::new(0); 5 + static INIT: Once = Once::new(); 6 + 7 + pub(crate) fn inside_proc_macro() -> bool { 8 + match WORKS.load(Ordering::Relaxed) { 9 + 1 => return false, 10 + 2 => return true, 11 + _ => {} 12 + } 13 + 14 + INIT.call_once(initialize); 15 + inside_proc_macro() 16 + } 17 + 18 + pub(crate) fn force_fallback() { 19 + WORKS.store(1, Ordering::Relaxed); 20 + } 21 + 22 + pub(crate) fn unforce_fallback() { 23 + initialize(); 24 + } 25 + 26 + #[cfg(not(no_is_available))] 27 + fn initialize() { 28 + let available = proc_macro::is_available(); 29 + WORKS.store(available as usize + 1, Ordering::Relaxed); 30 + } 31 + 32 + // Swap in a null panic hook to avoid printing "thread panicked" to stderr, 33 + // then use catch_unwind to determine whether the compiler's proc_macro is 34 + // working. When proc-macro2 is used from outside of a procedural macro all 35 + // of the proc_macro crate's APIs currently panic. 36 + // 37 + // The Once is to prevent the possibility of this ordering: 38 + // 39 + // thread 1 calls take_hook, gets the user's original hook 40 + // thread 1 calls set_hook with the null hook 41 + // thread 2 calls take_hook, thinks null hook is the original hook 42 + // thread 2 calls set_hook with the null hook 43 + // thread 1 calls set_hook with the actual original hook 44 + // thread 2 calls set_hook with what it thinks is the original hook 45 + // 46 + // in which the user's hook has been lost. 47 + // 48 + // There is still a race condition where a panic in a different thread can 49 + // happen during the interval that the user's original panic hook is 50 + // unregistered such that their hook is incorrectly not called. This is 51 + // sufficiently unlikely and less bad than printing panic messages to stderr 52 + // on correct use of this crate. Maybe there is a libstd feature request 53 + // here. For now, if a user needs to guarantee that this failure mode does 54 + // not occur, they need to call e.g. `proc_macro2::Span::call_site()` from 55 + // the main thread before launching any other threads. 56 + #[cfg(no_is_available)] 57 + fn initialize() { 58 + use std::panic::{self, PanicInfo}; 59 + 60 + type PanicHook = dyn Fn(&PanicInfo) + Sync + Send + 'static; 61 + 62 + let null_hook: Box<PanicHook> = Box::new(|_panic_info| { /* ignore */ }); 63 + let sanity_check = &*null_hook as *const PanicHook; 64 + let original_hook = panic::take_hook(); 65 + panic::set_hook(null_hook); 66 + 67 + let works = panic::catch_unwind(proc_macro::Span::call_site).is_ok(); 68 + WORKS.store(works as usize + 1, Ordering::Relaxed); 69 + 70 + let hopefully_null_hook = panic::take_hook(); 71 + panic::set_hook(original_hook); 72 + if sanity_check != &*hopefully_null_hook { 73 + panic!("observed race condition in proc_macro2::inside_proc_macro"); 74 + } 75 + }
+151
rust/proc-macro2/extra.rs
··· 1 + //! Items which do not have a correspondence to any API in the proc_macro crate, 2 + //! but are necessary to include in proc-macro2. 3 + 4 + use crate::fallback; 5 + use crate::imp; 6 + use crate::marker::{ProcMacroAutoTraits, MARKER}; 7 + use crate::Span; 8 + use core::fmt::{self, Debug}; 9 + 10 + /// Invalidate any `proc_macro2::Span` that exist on the current thread. 11 + /// 12 + /// The implementation of `Span` uses thread-local data structures and this 13 + /// function clears them. Calling any method on a `Span` on the current thread 14 + /// created prior to the invalidation will return incorrect values or crash. 15 + /// 16 + /// This function is useful for programs that process more than 2<sup>32</sup> 17 + /// bytes of Rust source code on the same thread. Just like rustc, proc-macro2 18 + /// uses 32-bit source locations, and these wrap around when the total source 19 + /// code processed by the same thread exceeds 2<sup>32</sup> bytes (4 20 + /// gigabytes). After a wraparound, `Span` methods such as `source_text()` can 21 + /// return wrong data. 22 + /// 23 + /// # Example 24 + /// 25 + /// As of late 2023, there is 200 GB of Rust code published on crates.io. 26 + /// Looking at just the newest version of every crate, it is 16 GB of code. So a 27 + /// workload that involves parsing it all would overflow a 32-bit source 28 + /// location unless spans are being invalidated. 29 + /// 30 + /// ``` 31 + /// use flate2::read::GzDecoder; 32 + /// use std::ffi::OsStr; 33 + /// use std::io::{BufReader, Read}; 34 + /// use std::str::FromStr; 35 + /// use tar::Archive; 36 + /// 37 + /// rayon::scope(|s| { 38 + /// for krate in every_version_of_every_crate() { 39 + /// s.spawn(move |_| { 40 + /// proc_macro2::extra::invalidate_current_thread_spans(); 41 + /// 42 + /// let reader = BufReader::new(krate); 43 + /// let tar = GzDecoder::new(reader); 44 + /// let mut archive = Archive::new(tar); 45 + /// for entry in archive.entries().unwrap() { 46 + /// let mut entry = entry.unwrap(); 47 + /// let path = entry.path().unwrap(); 48 + /// if path.extension() != Some(OsStr::new("rs")) { 49 + /// continue; 50 + /// } 51 + /// let mut content = String::new(); 52 + /// entry.read_to_string(&mut content).unwrap(); 53 + /// match proc_macro2::TokenStream::from_str(&content) { 54 + /// Ok(tokens) => {/* ... */}, 55 + /// Err(_) => continue, 56 + /// } 57 + /// } 58 + /// }); 59 + /// } 60 + /// }); 61 + /// # 62 + /// # fn every_version_of_every_crate() -> Vec<std::fs::File> { 63 + /// # Vec::new() 64 + /// # } 65 + /// ``` 66 + /// 67 + /// # Panics 68 + /// 69 + /// This function is not applicable to and will panic if called from a 70 + /// procedural macro. 71 + #[cfg(span_locations)] 72 + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] 73 + pub fn invalidate_current_thread_spans() { 74 + crate::imp::invalidate_current_thread_spans(); 75 + } 76 + 77 + /// An object that holds a [`Group`]'s `span_open()` and `span_close()` together 78 + /// in a more compact representation than holding those 2 spans individually. 79 + /// 80 + /// [`Group`]: crate::Group 81 + #[derive(Copy, Clone)] 82 + pub struct DelimSpan { 83 + inner: DelimSpanEnum, 84 + _marker: ProcMacroAutoTraits, 85 + } 86 + 87 + #[derive(Copy, Clone)] 88 + enum DelimSpanEnum { 89 + #[cfg(wrap_proc_macro)] 90 + Compiler { 91 + join: proc_macro::Span, 92 + open: proc_macro::Span, 93 + close: proc_macro::Span, 94 + }, 95 + Fallback(fallback::Span), 96 + } 97 + 98 + impl DelimSpan { 99 + pub(crate) fn new(group: &imp::Group) -> Self { 100 + #[cfg(wrap_proc_macro)] 101 + let inner = match group { 102 + imp::Group::Compiler(group) => DelimSpanEnum::Compiler { 103 + join: group.span(), 104 + open: group.span_open(), 105 + close: group.span_close(), 106 + }, 107 + imp::Group::Fallback(group) => DelimSpanEnum::Fallback(group.span()), 108 + }; 109 + 110 + #[cfg(not(wrap_proc_macro))] 111 + let inner = DelimSpanEnum::Fallback(group.span()); 112 + 113 + DelimSpan { 114 + inner, 115 + _marker: MARKER, 116 + } 117 + } 118 + 119 + /// Returns a span covering the entire delimited group. 120 + pub fn join(&self) -> Span { 121 + match &self.inner { 122 + #[cfg(wrap_proc_macro)] 123 + DelimSpanEnum::Compiler { join, .. } => Span::_new(imp::Span::Compiler(*join)), 124 + DelimSpanEnum::Fallback(span) => Span::_new_fallback(*span), 125 + } 126 + } 127 + 128 + /// Returns a span for the opening punctuation of the group only. 129 + pub fn open(&self) -> Span { 130 + match &self.inner { 131 + #[cfg(wrap_proc_macro)] 132 + DelimSpanEnum::Compiler { open, .. } => Span::_new(imp::Span::Compiler(*open)), 133 + DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.first_byte()), 134 + } 135 + } 136 + 137 + /// Returns a span for the closing punctuation of the group only. 138 + pub fn close(&self) -> Span { 139 + match &self.inner { 140 + #[cfg(wrap_proc_macro)] 141 + DelimSpanEnum::Compiler { close, .. } => Span::_new(imp::Span::Compiler(*close)), 142 + DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.last_byte()), 143 + } 144 + } 145 + } 146 + 147 + impl Debug for DelimSpan { 148 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 149 + Debug::fmt(&self.join(), f) 150 + } 151 + }
+1256
rust/proc-macro2/fallback.rs
··· 1 + #[cfg(wrap_proc_macro)] 2 + use crate::imp; 3 + #[cfg(span_locations)] 4 + use crate::location::LineColumn; 5 + use crate::parse::{self, Cursor}; 6 + use crate::rcvec::{RcVec, RcVecBuilder, RcVecIntoIter, RcVecMut}; 7 + use crate::{Delimiter, Spacing, TokenTree}; 8 + #[cfg(all(span_locations, not(fuzzing)))] 9 + use alloc::collections::BTreeMap; 10 + #[cfg(all(span_locations, not(fuzzing)))] 11 + use core::cell::RefCell; 12 + #[cfg(span_locations)] 13 + use core::cmp; 14 + #[cfg(all(span_locations, not(fuzzing)))] 15 + use core::cmp::Ordering; 16 + use core::fmt::{self, Debug, Display, Write}; 17 + use core::mem::ManuallyDrop; 18 + #[cfg(span_locations)] 19 + use core::ops::Range; 20 + use core::ops::RangeBounds; 21 + use core::ptr; 22 + use core::str; 23 + #[cfg(feature = "proc-macro")] 24 + use core::str::FromStr; 25 + use std::ffi::CStr; 26 + #[cfg(wrap_proc_macro)] 27 + use std::panic; 28 + #[cfg(span_locations)] 29 + use std::path::PathBuf; 30 + 31 + /// Force use of proc-macro2's fallback implementation of the API for now, even 32 + /// if the compiler's implementation is available. 33 + pub fn force() { 34 + #[cfg(wrap_proc_macro)] 35 + crate::detection::force_fallback(); 36 + } 37 + 38 + /// Resume using the compiler's implementation of the proc macro API if it is 39 + /// available. 40 + pub fn unforce() { 41 + #[cfg(wrap_proc_macro)] 42 + crate::detection::unforce_fallback(); 43 + } 44 + 45 + #[derive(Clone)] 46 + pub(crate) struct TokenStream { 47 + inner: RcVec<TokenTree>, 48 + } 49 + 50 + #[derive(Debug)] 51 + pub(crate) struct LexError { 52 + pub(crate) span: Span, 53 + } 54 + 55 + impl LexError { 56 + pub(crate) fn span(&self) -> Span { 57 + self.span 58 + } 59 + 60 + pub(crate) fn call_site() -> Self { 61 + LexError { 62 + span: Span::call_site(), 63 + } 64 + } 65 + } 66 + 67 + impl TokenStream { 68 + pub(crate) fn new() -> Self { 69 + TokenStream { 70 + inner: RcVecBuilder::new().build(), 71 + } 72 + } 73 + 74 + pub(crate) fn from_str_checked(src: &str) -> Result<Self, LexError> { 75 + // Create a dummy file & add it to the source map 76 + let mut cursor = get_cursor(src); 77 + 78 + // Strip a byte order mark if present 79 + const BYTE_ORDER_MARK: &str = "\u{feff}"; 80 + if cursor.starts_with(BYTE_ORDER_MARK) { 81 + cursor = cursor.advance(BYTE_ORDER_MARK.len()); 82 + } 83 + 84 + parse::token_stream(cursor) 85 + } 86 + 87 + #[cfg(feature = "proc-macro")] 88 + pub(crate) fn from_str_unchecked(src: &str) -> Self { 89 + Self::from_str_checked(src).unwrap() 90 + } 91 + 92 + pub(crate) fn is_empty(&self) -> bool { 93 + self.inner.len() == 0 94 + } 95 + 96 + fn take_inner(self) -> RcVecBuilder<TokenTree> { 97 + let nodrop = ManuallyDrop::new(self); 98 + unsafe { ptr::read(&nodrop.inner) }.make_owned() 99 + } 100 + } 101 + 102 + fn push_token_from_proc_macro(mut vec: RcVecMut<TokenTree>, token: TokenTree) { 103 + // https://github.com/dtolnay/proc-macro2/issues/235 104 + match token { 105 + TokenTree::Literal(crate::Literal { 106 + #[cfg(wrap_proc_macro)] 107 + inner: crate::imp::Literal::Fallback(literal), 108 + #[cfg(not(wrap_proc_macro))] 109 + inner: literal, 110 + .. 111 + }) if literal.repr.starts_with('-') => { 112 + push_negative_literal(vec, literal); 113 + } 114 + _ => vec.push(token), 115 + } 116 + 117 + #[cold] 118 + fn push_negative_literal(mut vec: RcVecMut<TokenTree>, mut literal: Literal) { 119 + literal.repr.remove(0); 120 + let mut punct = crate::Punct::new('-', Spacing::Alone); 121 + punct.set_span(crate::Span::_new_fallback(literal.span)); 122 + vec.push(TokenTree::Punct(punct)); 123 + vec.push(TokenTree::Literal(crate::Literal::_new_fallback(literal))); 124 + } 125 + } 126 + 127 + // Nonrecursive to prevent stack overflow. 128 + impl Drop for TokenStream { 129 + fn drop(&mut self) { 130 + let mut stack = Vec::new(); 131 + let mut current = match self.inner.get_mut() { 132 + Some(inner) => inner.take().into_iter(), 133 + None => return, 134 + }; 135 + loop { 136 + while let Some(token) = current.next() { 137 + let group = match token { 138 + TokenTree::Group(group) => group.inner, 139 + _ => continue, 140 + }; 141 + #[cfg(wrap_proc_macro)] 142 + let group = match group { 143 + crate::imp::Group::Fallback(group) => group, 144 + crate::imp::Group::Compiler(_) => continue, 145 + }; 146 + let mut group = group; 147 + if let Some(inner) = group.stream.inner.get_mut() { 148 + stack.push(current); 149 + current = inner.take().into_iter(); 150 + } 151 + } 152 + match stack.pop() { 153 + Some(next) => current = next, 154 + None => return, 155 + } 156 + } 157 + } 158 + } 159 + 160 + pub(crate) struct TokenStreamBuilder { 161 + inner: RcVecBuilder<TokenTree>, 162 + } 163 + 164 + impl TokenStreamBuilder { 165 + pub(crate) fn new() -> Self { 166 + TokenStreamBuilder { 167 + inner: RcVecBuilder::new(), 168 + } 169 + } 170 + 171 + pub(crate) fn with_capacity(cap: usize) -> Self { 172 + TokenStreamBuilder { 173 + inner: RcVecBuilder::with_capacity(cap), 174 + } 175 + } 176 + 177 + pub(crate) fn push_token_from_parser(&mut self, tt: TokenTree) { 178 + self.inner.push(tt); 179 + } 180 + 181 + pub(crate) fn build(self) -> TokenStream { 182 + TokenStream { 183 + inner: self.inner.build(), 184 + } 185 + } 186 + } 187 + 188 + #[cfg(span_locations)] 189 + fn get_cursor(src: &str) -> Cursor { 190 + #[cfg(fuzzing)] 191 + return Cursor { rest: src, off: 1 }; 192 + 193 + // Create a dummy file & add it to the source map 194 + #[cfg(not(fuzzing))] 195 + SOURCE_MAP.with(|sm| { 196 + let mut sm = sm.borrow_mut(); 197 + let span = sm.add_file(src); 198 + Cursor { 199 + rest: src, 200 + off: span.lo, 201 + } 202 + }) 203 + } 204 + 205 + #[cfg(not(span_locations))] 206 + fn get_cursor(src: &str) -> Cursor { 207 + Cursor { rest: src } 208 + } 209 + 210 + impl Display for LexError { 211 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 212 + f.write_str("cannot parse string into token stream") 213 + } 214 + } 215 + 216 + impl Display for TokenStream { 217 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 218 + let mut joint = false; 219 + for (i, tt) in self.inner.iter().enumerate() { 220 + if i != 0 && !joint { 221 + write!(f, " ")?; 222 + } 223 + joint = false; 224 + match tt { 225 + TokenTree::Group(tt) => Display::fmt(tt, f), 226 + TokenTree::Ident(tt) => Display::fmt(tt, f), 227 + TokenTree::Punct(tt) => { 228 + joint = tt.spacing() == Spacing::Joint; 229 + Display::fmt(tt, f) 230 + } 231 + TokenTree::Literal(tt) => Display::fmt(tt, f), 232 + }?; 233 + } 234 + 235 + Ok(()) 236 + } 237 + } 238 + 239 + impl Debug for TokenStream { 240 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 241 + f.write_str("TokenStream ")?; 242 + f.debug_list().entries(self.clone()).finish() 243 + } 244 + } 245 + 246 + #[cfg(feature = "proc-macro")] 247 + impl From<proc_macro::TokenStream> for TokenStream { 248 + fn from(inner: proc_macro::TokenStream) -> Self { 249 + TokenStream::from_str_unchecked(&inner.to_string()) 250 + } 251 + } 252 + 253 + #[cfg(feature = "proc-macro")] 254 + impl From<TokenStream> for proc_macro::TokenStream { 255 + fn from(inner: TokenStream) -> Self { 256 + proc_macro::TokenStream::from_str_unchecked(&inner.to_string()) 257 + } 258 + } 259 + 260 + impl From<TokenTree> for TokenStream { 261 + fn from(tree: TokenTree) -> Self { 262 + let mut stream = RcVecBuilder::new(); 263 + push_token_from_proc_macro(stream.as_mut(), tree); 264 + TokenStream { 265 + inner: stream.build(), 266 + } 267 + } 268 + } 269 + 270 + impl FromIterator<TokenTree> for TokenStream { 271 + fn from_iter<I: IntoIterator<Item = TokenTree>>(tokens: I) -> Self { 272 + let mut stream = TokenStream::new(); 273 + stream.extend(tokens); 274 + stream 275 + } 276 + } 277 + 278 + impl FromIterator<TokenStream> for TokenStream { 279 + fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self { 280 + let mut v = RcVecBuilder::new(); 281 + 282 + for stream in streams { 283 + v.extend(stream.take_inner()); 284 + } 285 + 286 + TokenStream { inner: v.build() } 287 + } 288 + } 289 + 290 + impl Extend<TokenTree> for TokenStream { 291 + fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, tokens: I) { 292 + let mut vec = self.inner.make_mut(); 293 + tokens 294 + .into_iter() 295 + .for_each(|token| push_token_from_proc_macro(vec.as_mut(), token)); 296 + } 297 + } 298 + 299 + impl Extend<TokenStream> for TokenStream { 300 + fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) { 301 + self.inner.make_mut().extend(streams.into_iter().flatten()); 302 + } 303 + } 304 + 305 + pub(crate) type TokenTreeIter = RcVecIntoIter<TokenTree>; 306 + 307 + impl IntoIterator for TokenStream { 308 + type Item = TokenTree; 309 + type IntoIter = TokenTreeIter; 310 + 311 + fn into_iter(self) -> TokenTreeIter { 312 + self.take_inner().into_iter() 313 + } 314 + } 315 + 316 + #[cfg(all(span_locations, not(fuzzing)))] 317 + thread_local! { 318 + static SOURCE_MAP: RefCell<SourceMap> = RefCell::new(SourceMap { 319 + // Start with a single dummy file which all call_site() and def_site() 320 + // spans reference. 321 + files: vec![FileInfo { 322 + source_text: String::new(), 323 + span: Span { lo: 0, hi: 0 }, 324 + lines: vec![0], 325 + char_index_to_byte_offset: BTreeMap::new(), 326 + }], 327 + }); 328 + } 329 + 330 + #[cfg(span_locations)] 331 + pub(crate) fn invalidate_current_thread_spans() { 332 + #[cfg(not(fuzzing))] 333 + SOURCE_MAP.with(|sm| sm.borrow_mut().files.truncate(1)); 334 + } 335 + 336 + #[cfg(all(span_locations, not(fuzzing)))] 337 + struct FileInfo { 338 + source_text: String, 339 + span: Span, 340 + lines: Vec<usize>, 341 + char_index_to_byte_offset: BTreeMap<usize, usize>, 342 + } 343 + 344 + #[cfg(all(span_locations, not(fuzzing)))] 345 + impl FileInfo { 346 + fn offset_line_column(&self, offset: usize) -> LineColumn { 347 + assert!(self.span_within(Span { 348 + lo: offset as u32, 349 + hi: offset as u32, 350 + })); 351 + let offset = offset - self.span.lo as usize; 352 + match self.lines.binary_search(&offset) { 353 + Ok(found) => LineColumn { 354 + line: found + 1, 355 + column: 0, 356 + }, 357 + Err(idx) => LineColumn { 358 + line: idx, 359 + column: offset - self.lines[idx - 1], 360 + }, 361 + } 362 + } 363 + 364 + fn span_within(&self, span: Span) -> bool { 365 + span.lo >= self.span.lo && span.hi <= self.span.hi 366 + } 367 + 368 + fn byte_range(&mut self, span: Span) -> Range<usize> { 369 + let lo_char = (span.lo - self.span.lo) as usize; 370 + 371 + // Look up offset of the largest already-computed char index that is 372 + // less than or equal to the current requested one. We resume counting 373 + // chars from that point. 374 + let (&last_char_index, &last_byte_offset) = self 375 + .char_index_to_byte_offset 376 + .range(..=lo_char) 377 + .next_back() 378 + .unwrap_or((&0, &0)); 379 + 380 + let lo_byte = if last_char_index == lo_char { 381 + last_byte_offset 382 + } else { 383 + let total_byte_offset = match self.source_text[last_byte_offset..] 384 + .char_indices() 385 + .nth(lo_char - last_char_index) 386 + { 387 + Some((additional_offset, _ch)) => last_byte_offset + additional_offset, 388 + None => self.source_text.len(), 389 + }; 390 + self.char_index_to_byte_offset 391 + .insert(lo_char, total_byte_offset); 392 + total_byte_offset 393 + }; 394 + 395 + let trunc_lo = &self.source_text[lo_byte..]; 396 + let char_len = (span.hi - span.lo) as usize; 397 + lo_byte..match trunc_lo.char_indices().nth(char_len) { 398 + Some((offset, _ch)) => lo_byte + offset, 399 + None => self.source_text.len(), 400 + } 401 + } 402 + 403 + fn source_text(&mut self, span: Span) -> String { 404 + let byte_range = self.byte_range(span); 405 + self.source_text[byte_range].to_owned() 406 + } 407 + } 408 + 409 + /// Computes the offsets of each line in the given source string 410 + /// and the total number of characters 411 + #[cfg(all(span_locations, not(fuzzing)))] 412 + fn lines_offsets(s: &str) -> (usize, Vec<usize>) { 413 + let mut lines = vec![0]; 414 + let mut total = 0; 415 + 416 + for ch in s.chars() { 417 + total += 1; 418 + if ch == '\n' { 419 + lines.push(total); 420 + } 421 + } 422 + 423 + (total, lines) 424 + } 425 + 426 + #[cfg(all(span_locations, not(fuzzing)))] 427 + struct SourceMap { 428 + files: Vec<FileInfo>, 429 + } 430 + 431 + #[cfg(all(span_locations, not(fuzzing)))] 432 + impl SourceMap { 433 + fn next_start_pos(&self) -> u32 { 434 + // Add 1 so there's always space between files. 435 + // 436 + // We'll always have at least 1 file, as we initialize our files list 437 + // with a dummy file. 438 + self.files.last().unwrap().span.hi + 1 439 + } 440 + 441 + fn add_file(&mut self, src: &str) -> Span { 442 + let (len, lines) = lines_offsets(src); 443 + let lo = self.next_start_pos(); 444 + let span = Span { 445 + lo, 446 + hi: lo + (len as u32), 447 + }; 448 + 449 + self.files.push(FileInfo { 450 + source_text: src.to_owned(), 451 + span, 452 + lines, 453 + // Populated lazily by source_text(). 454 + char_index_to_byte_offset: BTreeMap::new(), 455 + }); 456 + 457 + span 458 + } 459 + 460 + fn find(&self, span: Span) -> usize { 461 + match self.files.binary_search_by(|file| { 462 + if file.span.hi < span.lo { 463 + Ordering::Less 464 + } else if file.span.lo > span.hi { 465 + Ordering::Greater 466 + } else { 467 + assert!(file.span_within(span)); 468 + Ordering::Equal 469 + } 470 + }) { 471 + Ok(i) => i, 472 + Err(_) => unreachable!("Invalid span with no related FileInfo!"), 473 + } 474 + } 475 + 476 + fn filepath(&self, span: Span) -> String { 477 + let i = self.find(span); 478 + if i == 0 { 479 + "<unspecified>".to_owned() 480 + } else { 481 + format!("<parsed string {}>", i) 482 + } 483 + } 484 + 485 + fn fileinfo(&self, span: Span) -> &FileInfo { 486 + let i = self.find(span); 487 + &self.files[i] 488 + } 489 + 490 + fn fileinfo_mut(&mut self, span: Span) -> &mut FileInfo { 491 + let i = self.find(span); 492 + &mut self.files[i] 493 + } 494 + } 495 + 496 + #[derive(Clone, Copy, PartialEq, Eq)] 497 + pub(crate) struct Span { 498 + #[cfg(span_locations)] 499 + pub(crate) lo: u32, 500 + #[cfg(span_locations)] 501 + pub(crate) hi: u32, 502 + } 503 + 504 + impl Span { 505 + #[cfg(not(span_locations))] 506 + pub(crate) fn call_site() -> Self { 507 + Span {} 508 + } 509 + 510 + #[cfg(span_locations)] 511 + pub(crate) fn call_site() -> Self { 512 + Span { lo: 0, hi: 0 } 513 + } 514 + 515 + pub(crate) fn mixed_site() -> Self { 516 + Span::call_site() 517 + } 518 + 519 + #[cfg(procmacro2_semver_exempt)] 520 + pub(crate) fn def_site() -> Self { 521 + Span::call_site() 522 + } 523 + 524 + pub(crate) fn resolved_at(&self, _other: Span) -> Span { 525 + // Stable spans consist only of line/column information, so 526 + // `resolved_at` and `located_at` only select which span the 527 + // caller wants line/column information from. 528 + *self 529 + } 530 + 531 + pub(crate) fn located_at(&self, other: Span) -> Span { 532 + other 533 + } 534 + 535 + #[cfg(span_locations)] 536 + pub(crate) fn byte_range(&self) -> Range<usize> { 537 + #[cfg(fuzzing)] 538 + return 0..0; 539 + 540 + #[cfg(not(fuzzing))] 541 + { 542 + if self.is_call_site() { 543 + 0..0 544 + } else { 545 + SOURCE_MAP.with(|sm| sm.borrow_mut().fileinfo_mut(*self).byte_range(*self)) 546 + } 547 + } 548 + } 549 + 550 + #[cfg(span_locations)] 551 + pub(crate) fn start(&self) -> LineColumn { 552 + #[cfg(fuzzing)] 553 + return LineColumn { line: 0, column: 0 }; 554 + 555 + #[cfg(not(fuzzing))] 556 + SOURCE_MAP.with(|sm| { 557 + let sm = sm.borrow(); 558 + let fi = sm.fileinfo(*self); 559 + fi.offset_line_column(self.lo as usize) 560 + }) 561 + } 562 + 563 + #[cfg(span_locations)] 564 + pub(crate) fn end(&self) -> LineColumn { 565 + #[cfg(fuzzing)] 566 + return LineColumn { line: 0, column: 0 }; 567 + 568 + #[cfg(not(fuzzing))] 569 + SOURCE_MAP.with(|sm| { 570 + let sm = sm.borrow(); 571 + let fi = sm.fileinfo(*self); 572 + fi.offset_line_column(self.hi as usize) 573 + }) 574 + } 575 + 576 + #[cfg(span_locations)] 577 + pub(crate) fn file(&self) -> String { 578 + #[cfg(fuzzing)] 579 + return "<unspecified>".to_owned(); 580 + 581 + #[cfg(not(fuzzing))] 582 + SOURCE_MAP.with(|sm| { 583 + let sm = sm.borrow(); 584 + sm.filepath(*self) 585 + }) 586 + } 587 + 588 + #[cfg(span_locations)] 589 + pub(crate) fn local_file(&self) -> Option<PathBuf> { 590 + None 591 + } 592 + 593 + #[cfg(not(span_locations))] 594 + pub(crate) fn join(&self, _other: Span) -> Option<Span> { 595 + Some(Span {}) 596 + } 597 + 598 + #[cfg(span_locations)] 599 + pub(crate) fn join(&self, other: Span) -> Option<Span> { 600 + #[cfg(fuzzing)] 601 + return { 602 + let _ = other; 603 + None 604 + }; 605 + 606 + #[cfg(not(fuzzing))] 607 + SOURCE_MAP.with(|sm| { 608 + let sm = sm.borrow(); 609 + // If `other` is not within the same FileInfo as us, return None. 610 + if !sm.fileinfo(*self).span_within(other) { 611 + return None; 612 + } 613 + Some(Span { 614 + lo: cmp::min(self.lo, other.lo), 615 + hi: cmp::max(self.hi, other.hi), 616 + }) 617 + }) 618 + } 619 + 620 + #[cfg(not(span_locations))] 621 + pub(crate) fn source_text(&self) -> Option<String> { 622 + None 623 + } 624 + 625 + #[cfg(span_locations)] 626 + pub(crate) fn source_text(&self) -> Option<String> { 627 + #[cfg(fuzzing)] 628 + return None; 629 + 630 + #[cfg(not(fuzzing))] 631 + { 632 + if self.is_call_site() { 633 + None 634 + } else { 635 + Some(SOURCE_MAP.with(|sm| sm.borrow_mut().fileinfo_mut(*self).source_text(*self))) 636 + } 637 + } 638 + } 639 + 640 + #[cfg(not(span_locations))] 641 + pub(crate) fn first_byte(self) -> Self { 642 + self 643 + } 644 + 645 + #[cfg(span_locations)] 646 + pub(crate) fn first_byte(self) -> Self { 647 + Span { 648 + lo: self.lo, 649 + hi: cmp::min(self.lo.saturating_add(1), self.hi), 650 + } 651 + } 652 + 653 + #[cfg(not(span_locations))] 654 + pub(crate) fn last_byte(self) -> Self { 655 + self 656 + } 657 + 658 + #[cfg(span_locations)] 659 + pub(crate) fn last_byte(self) -> Self { 660 + Span { 661 + lo: cmp::max(self.hi.saturating_sub(1), self.lo), 662 + hi: self.hi, 663 + } 664 + } 665 + 666 + #[cfg(span_locations)] 667 + fn is_call_site(&self) -> bool { 668 + self.lo == 0 && self.hi == 0 669 + } 670 + } 671 + 672 + impl Debug for Span { 673 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 674 + #[cfg(span_locations)] 675 + return write!(f, "bytes({}..{})", self.lo, self.hi); 676 + 677 + #[cfg(not(span_locations))] 678 + write!(f, "Span") 679 + } 680 + } 681 + 682 + pub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) { 683 + #[cfg(span_locations)] 684 + { 685 + if span.is_call_site() { 686 + return; 687 + } 688 + } 689 + 690 + if cfg!(span_locations) { 691 + debug.field("span", &span); 692 + } 693 + } 694 + 695 + #[derive(Clone)] 696 + pub(crate) struct Group { 697 + delimiter: Delimiter, 698 + stream: TokenStream, 699 + span: Span, 700 + } 701 + 702 + impl Group { 703 + pub(crate) fn new(delimiter: Delimiter, stream: TokenStream) -> Self { 704 + Group { 705 + delimiter, 706 + stream, 707 + span: Span::call_site(), 708 + } 709 + } 710 + 711 + pub(crate) fn delimiter(&self) -> Delimiter { 712 + self.delimiter 713 + } 714 + 715 + pub(crate) fn stream(&self) -> TokenStream { 716 + self.stream.clone() 717 + } 718 + 719 + pub(crate) fn span(&self) -> Span { 720 + self.span 721 + } 722 + 723 + pub(crate) fn span_open(&self) -> Span { 724 + self.span.first_byte() 725 + } 726 + 727 + pub(crate) fn span_close(&self) -> Span { 728 + self.span.last_byte() 729 + } 730 + 731 + pub(crate) fn set_span(&mut self, span: Span) { 732 + self.span = span; 733 + } 734 + } 735 + 736 + impl Display for Group { 737 + // We attempt to match libproc_macro's formatting. 738 + // Empty parens: () 739 + // Nonempty parens: (...) 740 + // Empty brackets: [] 741 + // Nonempty brackets: [...] 742 + // Empty braces: { } 743 + // Nonempty braces: { ... } 744 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 745 + let (open, close) = match self.delimiter { 746 + Delimiter::Parenthesis => ("(", ")"), 747 + Delimiter::Brace => ("{ ", "}"), 748 + Delimiter::Bracket => ("[", "]"), 749 + Delimiter::None => ("", ""), 750 + }; 751 + 752 + f.write_str(open)?; 753 + Display::fmt(&self.stream, f)?; 754 + if self.delimiter == Delimiter::Brace && !self.stream.inner.is_empty() { 755 + f.write_str(" ")?; 756 + } 757 + f.write_str(close)?; 758 + 759 + Ok(()) 760 + } 761 + } 762 + 763 + impl Debug for Group { 764 + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 765 + let mut debug = fmt.debug_struct("Group"); 766 + debug.field("delimiter", &self.delimiter); 767 + debug.field("stream", &self.stream); 768 + debug_span_field_if_nontrivial(&mut debug, self.span); 769 + debug.finish() 770 + } 771 + } 772 + 773 + #[derive(Clone)] 774 + pub(crate) struct Ident { 775 + sym: Box<str>, 776 + span: Span, 777 + raw: bool, 778 + } 779 + 780 + impl Ident { 781 + #[track_caller] 782 + pub(crate) fn new_checked(string: &str, span: Span) -> Self { 783 + validate_ident(string); 784 + Ident::new_unchecked(string, span) 785 + } 786 + 787 + pub(crate) fn new_unchecked(string: &str, span: Span) -> Self { 788 + Ident { 789 + sym: Box::from(string), 790 + span, 791 + raw: false, 792 + } 793 + } 794 + 795 + #[track_caller] 796 + pub(crate) fn new_raw_checked(string: &str, span: Span) -> Self { 797 + validate_ident_raw(string); 798 + Ident::new_raw_unchecked(string, span) 799 + } 800 + 801 + pub(crate) fn new_raw_unchecked(string: &str, span: Span) -> Self { 802 + Ident { 803 + sym: Box::from(string), 804 + span, 805 + raw: true, 806 + } 807 + } 808 + 809 + pub(crate) fn span(&self) -> Span { 810 + self.span 811 + } 812 + 813 + pub(crate) fn set_span(&mut self, span: Span) { 814 + self.span = span; 815 + } 816 + } 817 + 818 + pub(crate) fn is_ident_start(c: char) -> bool { 819 + c == '_' || unicode_ident::is_xid_start(c) 820 + } 821 + 822 + pub(crate) fn is_ident_continue(c: char) -> bool { 823 + unicode_ident::is_xid_continue(c) 824 + } 825 + 826 + #[track_caller] 827 + fn validate_ident(string: &str) { 828 + if string.is_empty() { 829 + panic!("Ident is not allowed to be empty; use Option<Ident>"); 830 + } 831 + 832 + if string.bytes().all(|digit| b'0' <= digit && digit <= b'9') { 833 + panic!("Ident cannot be a number; use Literal instead"); 834 + } 835 + 836 + fn ident_ok(string: &str) -> bool { 837 + let mut chars = string.chars(); 838 + let first = chars.next().unwrap(); 839 + if !is_ident_start(first) { 840 + return false; 841 + } 842 + for ch in chars { 843 + if !is_ident_continue(ch) { 844 + return false; 845 + } 846 + } 847 + true 848 + } 849 + 850 + if !ident_ok(string) { 851 + panic!("{:?} is not a valid Ident", string); 852 + } 853 + } 854 + 855 + #[track_caller] 856 + fn validate_ident_raw(string: &str) { 857 + validate_ident(string); 858 + 859 + match string { 860 + "_" | "super" | "self" | "Self" | "crate" => { 861 + panic!("`r#{}` cannot be a raw identifier", string); 862 + } 863 + _ => {} 864 + } 865 + } 866 + 867 + impl PartialEq for Ident { 868 + fn eq(&self, other: &Ident) -> bool { 869 + self.sym == other.sym && self.raw == other.raw 870 + } 871 + } 872 + 873 + impl<T> PartialEq<T> for Ident 874 + where 875 + T: ?Sized + AsRef<str>, 876 + { 877 + fn eq(&self, other: &T) -> bool { 878 + let other = other.as_ref(); 879 + if self.raw { 880 + other.starts_with("r#") && *self.sym == other[2..] 881 + } else { 882 + *self.sym == *other 883 + } 884 + } 885 + } 886 + 887 + impl Display for Ident { 888 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 889 + if self.raw { 890 + f.write_str("r#")?; 891 + } 892 + Display::fmt(&self.sym, f) 893 + } 894 + } 895 + 896 + #[allow(clippy::missing_fields_in_debug)] 897 + impl Debug for Ident { 898 + // Ident(proc_macro), Ident(r#union) 899 + #[cfg(not(span_locations))] 900 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 901 + let mut debug = f.debug_tuple("Ident"); 902 + debug.field(&format_args!("{}", self)); 903 + debug.finish() 904 + } 905 + 906 + // Ident { 907 + // sym: proc_macro, 908 + // span: bytes(128..138) 909 + // } 910 + #[cfg(span_locations)] 911 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 912 + let mut debug = f.debug_struct("Ident"); 913 + debug.field("sym", &format_args!("{}", self)); 914 + debug_span_field_if_nontrivial(&mut debug, self.span); 915 + debug.finish() 916 + } 917 + } 918 + 919 + #[derive(Clone)] 920 + pub(crate) struct Literal { 921 + pub(crate) repr: String, 922 + span: Span, 923 + } 924 + 925 + macro_rules! suffixed_numbers { 926 + ($($name:ident => $kind:ident,)*) => ($( 927 + pub(crate) fn $name(n: $kind) -> Literal { 928 + Literal::_new(format!(concat!("{}", stringify!($kind)), n)) 929 + } 930 + )*) 931 + } 932 + 933 + macro_rules! unsuffixed_numbers { 934 + ($($name:ident => $kind:ident,)*) => ($( 935 + pub(crate) fn $name(n: $kind) -> Literal { 936 + Literal::_new(n.to_string()) 937 + } 938 + )*) 939 + } 940 + 941 + impl Literal { 942 + pub(crate) fn _new(repr: String) -> Self { 943 + Literal { 944 + repr, 945 + span: Span::call_site(), 946 + } 947 + } 948 + 949 + pub(crate) fn from_str_checked(repr: &str) -> Result<Self, LexError> { 950 + let mut cursor = get_cursor(repr); 951 + #[cfg(span_locations)] 952 + let lo = cursor.off; 953 + 954 + let negative = cursor.starts_with_char('-'); 955 + if negative { 956 + cursor = cursor.advance(1); 957 + if !cursor.starts_with_fn(|ch| ch.is_ascii_digit()) { 958 + return Err(LexError::call_site()); 959 + } 960 + } 961 + 962 + if let Ok((rest, mut literal)) = parse::literal(cursor) { 963 + if rest.is_empty() { 964 + if negative { 965 + literal.repr.insert(0, '-'); 966 + } 967 + literal.span = Span { 968 + #[cfg(span_locations)] 969 + lo, 970 + #[cfg(span_locations)] 971 + hi: rest.off, 972 + }; 973 + return Ok(literal); 974 + } 975 + } 976 + Err(LexError::call_site()) 977 + } 978 + 979 + pub(crate) unsafe fn from_str_unchecked(repr: &str) -> Self { 980 + Literal::_new(repr.to_owned()) 981 + } 982 + 983 + suffixed_numbers! { 984 + u8_suffixed => u8, 985 + u16_suffixed => u16, 986 + u32_suffixed => u32, 987 + u64_suffixed => u64, 988 + u128_suffixed => u128, 989 + usize_suffixed => usize, 990 + i8_suffixed => i8, 991 + i16_suffixed => i16, 992 + i32_suffixed => i32, 993 + i64_suffixed => i64, 994 + i128_suffixed => i128, 995 + isize_suffixed => isize, 996 + 997 + f32_suffixed => f32, 998 + f64_suffixed => f64, 999 + } 1000 + 1001 + unsuffixed_numbers! { 1002 + u8_unsuffixed => u8, 1003 + u16_unsuffixed => u16, 1004 + u32_unsuffixed => u32, 1005 + u64_unsuffixed => u64, 1006 + u128_unsuffixed => u128, 1007 + usize_unsuffixed => usize, 1008 + i8_unsuffixed => i8, 1009 + i16_unsuffixed => i16, 1010 + i32_unsuffixed => i32, 1011 + i64_unsuffixed => i64, 1012 + i128_unsuffixed => i128, 1013 + isize_unsuffixed => isize, 1014 + } 1015 + 1016 + pub(crate) fn f32_unsuffixed(f: f32) -> Literal { 1017 + let mut s = f.to_string(); 1018 + if !s.contains('.') { 1019 + s.push_str(".0"); 1020 + } 1021 + Literal::_new(s) 1022 + } 1023 + 1024 + pub(crate) fn f64_unsuffixed(f: f64) -> Literal { 1025 + let mut s = f.to_string(); 1026 + if !s.contains('.') { 1027 + s.push_str(".0"); 1028 + } 1029 + Literal::_new(s) 1030 + } 1031 + 1032 + pub(crate) fn string(string: &str) -> Literal { 1033 + let mut repr = String::with_capacity(string.len() + 2); 1034 + repr.push('"'); 1035 + escape_utf8(string, &mut repr); 1036 + repr.push('"'); 1037 + Literal::_new(repr) 1038 + } 1039 + 1040 + pub(crate) fn character(ch: char) -> Literal { 1041 + let mut repr = String::new(); 1042 + repr.push('\''); 1043 + if ch == '"' { 1044 + // escape_debug turns this into '\"' which is unnecessary. 1045 + repr.push(ch); 1046 + } else { 1047 + repr.extend(ch.escape_debug()); 1048 + } 1049 + repr.push('\''); 1050 + Literal::_new(repr) 1051 + } 1052 + 1053 + pub(crate) fn byte_character(byte: u8) -> Literal { 1054 + let mut repr = "b'".to_string(); 1055 + #[allow(clippy::match_overlapping_arm)] 1056 + match byte { 1057 + b'\0' => repr.push_str(r"\0"), 1058 + b'\t' => repr.push_str(r"\t"), 1059 + b'\n' => repr.push_str(r"\n"), 1060 + b'\r' => repr.push_str(r"\r"), 1061 + b'\'' => repr.push_str(r"\'"), 1062 + b'\\' => repr.push_str(r"\\"), 1063 + b'\x20'..=b'\x7E' => repr.push(byte as char), 1064 + _ => { 1065 + let _ = write!(repr, r"\x{:02X}", byte); 1066 + } 1067 + } 1068 + repr.push('\''); 1069 + Literal::_new(repr) 1070 + } 1071 + 1072 + pub(crate) fn byte_string(bytes: &[u8]) -> Literal { 1073 + let mut repr = "b\"".to_string(); 1074 + let mut bytes = bytes.iter(); 1075 + while let Some(&b) = bytes.next() { 1076 + #[allow(clippy::match_overlapping_arm)] 1077 + match b { 1078 + b'\0' => repr.push_str(match bytes.as_slice().first() { 1079 + // circumvent clippy::octal_escapes lint 1080 + Some(b'0'..=b'7') => r"\x00", 1081 + _ => r"\0", 1082 + }), 1083 + b'\t' => repr.push_str(r"\t"), 1084 + b'\n' => repr.push_str(r"\n"), 1085 + b'\r' => repr.push_str(r"\r"), 1086 + b'"' => repr.push_str("\\\""), 1087 + b'\\' => repr.push_str(r"\\"), 1088 + b'\x20'..=b'\x7E' => repr.push(b as char), 1089 + _ => { 1090 + let _ = write!(repr, r"\x{:02X}", b); 1091 + } 1092 + } 1093 + } 1094 + repr.push('"'); 1095 + Literal::_new(repr) 1096 + } 1097 + 1098 + pub(crate) fn c_string(string: &CStr) -> Literal { 1099 + let mut repr = "c\"".to_string(); 1100 + let mut bytes = string.to_bytes(); 1101 + while !bytes.is_empty() { 1102 + let (valid, invalid) = match str::from_utf8(bytes) { 1103 + Ok(all_valid) => { 1104 + bytes = b""; 1105 + (all_valid, bytes) 1106 + } 1107 + Err(utf8_error) => { 1108 + let (valid, rest) = bytes.split_at(utf8_error.valid_up_to()); 1109 + let valid = str::from_utf8(valid).unwrap(); 1110 + let invalid = utf8_error 1111 + .error_len() 1112 + .map_or(rest, |error_len| &rest[..error_len]); 1113 + bytes = &bytes[valid.len() + invalid.len()..]; 1114 + (valid, invalid) 1115 + } 1116 + }; 1117 + escape_utf8(valid, &mut repr); 1118 + for &byte in invalid { 1119 + let _ = write!(repr, r"\x{:02X}", byte); 1120 + } 1121 + } 1122 + repr.push('"'); 1123 + Literal::_new(repr) 1124 + } 1125 + 1126 + pub(crate) fn span(&self) -> Span { 1127 + self.span 1128 + } 1129 + 1130 + pub(crate) fn set_span(&mut self, span: Span) { 1131 + self.span = span; 1132 + } 1133 + 1134 + pub(crate) fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> { 1135 + #[cfg(not(span_locations))] 1136 + { 1137 + let _ = range; 1138 + None 1139 + } 1140 + 1141 + #[cfg(span_locations)] 1142 + { 1143 + use core::ops::Bound; 1144 + 1145 + let lo = match range.start_bound() { 1146 + Bound::Included(start) => { 1147 + let start = u32::try_from(*start).ok()?; 1148 + self.span.lo.checked_add(start)? 1149 + } 1150 + Bound::Excluded(start) => { 1151 + let start = u32::try_from(*start).ok()?; 1152 + self.span.lo.checked_add(start)?.checked_add(1)? 1153 + } 1154 + Bound::Unbounded => self.span.lo, 1155 + }; 1156 + let hi = match range.end_bound() { 1157 + Bound::Included(end) => { 1158 + let end = u32::try_from(*end).ok()?; 1159 + self.span.lo.checked_add(end)?.checked_add(1)? 1160 + } 1161 + Bound::Excluded(end) => { 1162 + let end = u32::try_from(*end).ok()?; 1163 + self.span.lo.checked_add(end)? 1164 + } 1165 + Bound::Unbounded => self.span.hi, 1166 + }; 1167 + if lo <= hi && hi <= self.span.hi { 1168 + Some(Span { lo, hi }) 1169 + } else { 1170 + None 1171 + } 1172 + } 1173 + } 1174 + } 1175 + 1176 + impl Display for Literal { 1177 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1178 + Display::fmt(&self.repr, f) 1179 + } 1180 + } 1181 + 1182 + impl Debug for Literal { 1183 + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 1184 + let mut debug = fmt.debug_struct("Literal"); 1185 + debug.field("lit", &format_args!("{}", self.repr)); 1186 + debug_span_field_if_nontrivial(&mut debug, self.span); 1187 + debug.finish() 1188 + } 1189 + } 1190 + 1191 + fn escape_utf8(string: &str, repr: &mut String) { 1192 + let mut chars = string.chars(); 1193 + while let Some(ch) = chars.next() { 1194 + if ch == '\0' { 1195 + repr.push_str( 1196 + if chars 1197 + .as_str() 1198 + .starts_with(|next| '0' <= next && next <= '7') 1199 + { 1200 + // circumvent clippy::octal_escapes lint 1201 + r"\x00" 1202 + } else { 1203 + r"\0" 1204 + }, 1205 + ); 1206 + } else if ch == '\'' { 1207 + // escape_debug turns this into "\'" which is unnecessary. 1208 + repr.push(ch); 1209 + } else { 1210 + repr.extend(ch.escape_debug()); 1211 + } 1212 + } 1213 + } 1214 + 1215 + #[cfg(feature = "proc-macro")] 1216 + pub(crate) trait FromStr2: FromStr<Err = proc_macro::LexError> { 1217 + #[cfg(wrap_proc_macro)] 1218 + fn valid(src: &str) -> bool; 1219 + 1220 + #[cfg(wrap_proc_macro)] 1221 + fn from_str_checked(src: &str) -> Result<Self, imp::LexError> { 1222 + // Validate using fallback parser, because rustc is incapable of 1223 + // returning a recoverable Err for certain invalid token streams, and 1224 + // will instead permanently poison the compilation. 1225 + if !Self::valid(src) { 1226 + return Err(imp::LexError::CompilerPanic); 1227 + } 1228 + 1229 + // Catch panic to work around https://github.com/rust-lang/rust/issues/58736. 1230 + match panic::catch_unwind(|| Self::from_str(src)) { 1231 + Ok(Ok(ok)) => Ok(ok), 1232 + Ok(Err(lex)) => Err(imp::LexError::Compiler(lex)), 1233 + Err(_panic) => Err(imp::LexError::CompilerPanic), 1234 + } 1235 + } 1236 + 1237 + fn from_str_unchecked(src: &str) -> Self { 1238 + Self::from_str(src).unwrap() 1239 + } 1240 + } 1241 + 1242 + #[cfg(feature = "proc-macro")] 1243 + impl FromStr2 for proc_macro::TokenStream { 1244 + #[cfg(wrap_proc_macro)] 1245 + fn valid(src: &str) -> bool { 1246 + TokenStream::from_str_checked(src).is_ok() 1247 + } 1248 + } 1249 + 1250 + #[cfg(feature = "proc-macro")] 1251 + impl FromStr2 for proc_macro::Literal { 1252 + #[cfg(wrap_proc_macro)] 1253 + fn valid(src: &str) -> bool { 1254 + Literal::from_str_checked(src).is_ok() 1255 + } 1256 + }
+1349
rust/proc-macro2/lib.rs
··· 1 + //! [![github]](https://github.com/dtolnay/proc-macro2)&ensp;[![crates-io]](https://crates.io/crates/proc-macro2)&ensp;[![docs-rs]](crate) 2 + //! 3 + //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github 4 + //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust 5 + //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs 6 + //! 7 + //! <br> 8 + //! 9 + //! A wrapper around the procedural macro API of the compiler's [`proc_macro`] 10 + //! crate. This library serves two purposes: 11 + //! 12 + //! - **Bring proc-macro-like functionality to other contexts like build.rs and 13 + //! main.rs.** Types from `proc_macro` are entirely specific to procedural 14 + //! macros and cannot ever exist in code outside of a procedural macro. 15 + //! Meanwhile `proc_macro2` types may exist anywhere including non-macro code. 16 + //! By developing foundational libraries like [syn] and [quote] against 17 + //! `proc_macro2` rather than `proc_macro`, the procedural macro ecosystem 18 + //! becomes easily applicable to many other use cases and we avoid 19 + //! reimplementing non-macro equivalents of those libraries. 20 + //! 21 + //! - **Make procedural macros unit testable.** As a consequence of being 22 + //! specific to procedural macros, nothing that uses `proc_macro` can be 23 + //! executed from a unit test. In order for helper libraries or components of 24 + //! a macro to be testable in isolation, they must be implemented using 25 + //! `proc_macro2`. 26 + //! 27 + //! [syn]: https://github.com/dtolnay/syn 28 + //! [quote]: https://github.com/dtolnay/quote 29 + //! 30 + //! # Usage 31 + //! 32 + //! The skeleton of a typical procedural macro typically looks like this: 33 + //! 34 + //! ``` 35 + //! extern crate proc_macro; 36 + //! 37 + //! # const IGNORE: &str = stringify! { 38 + //! #[proc_macro_derive(MyDerive)] 39 + //! # }; 40 + //! # #[cfg(wrap_proc_macro)] 41 + //! pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { 42 + //! let input = proc_macro2::TokenStream::from(input); 43 + //! 44 + //! let output: proc_macro2::TokenStream = { 45 + //! /* transform input */ 46 + //! # input 47 + //! }; 48 + //! 49 + //! proc_macro::TokenStream::from(output) 50 + //! } 51 + //! ``` 52 + //! 53 + //! If parsing with [Syn], you'll use [`parse_macro_input!`] instead to 54 + //! propagate parse errors correctly back to the compiler when parsing fails. 55 + //! 56 + //! [`parse_macro_input!`]: https://docs.rs/syn/2.0/syn/macro.parse_macro_input.html 57 + //! 58 + //! # Unstable features 59 + //! 60 + //! The default feature set of proc-macro2 tracks the most recent stable 61 + //! compiler API. Functionality in `proc_macro` that is not yet stable is not 62 + //! exposed by proc-macro2 by default. 63 + //! 64 + //! To opt into the additional APIs available in the most recent nightly 65 + //! compiler, the `procmacro2_semver_exempt` config flag must be passed to 66 + //! rustc. We will polyfill those nightly-only APIs back to Rust 1.56.0. As 67 + //! these are unstable APIs that track the nightly compiler, minor versions of 68 + //! proc-macro2 may make breaking changes to them at any time. 69 + //! 70 + //! ```sh 71 + //! RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build 72 + //! ``` 73 + //! 74 + //! Note that this must not only be done for your crate, but for any crate that 75 + //! depends on your crate. This infectious nature is intentional, as it serves 76 + //! as a reminder that you are outside of the normal semver guarantees. 77 + //! 78 + //! Semver exempt methods are marked as such in the proc-macro2 documentation. 79 + //! 80 + //! # Thread-Safety 81 + //! 82 + //! Most types in this crate are `!Sync` because the underlying compiler 83 + //! types make use of thread-local memory, meaning they cannot be accessed from 84 + //! a different thread. 85 + 86 + // Proc-macro2 types in rustdoc of other crates get linked to here. 87 + #![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.101")] 88 + #![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))] 89 + #![cfg_attr(super_unstable, feature(proc_macro_def_site))] 90 + #![cfg_attr(docsrs, feature(doc_cfg))] 91 + #![deny(unsafe_op_in_unsafe_fn)] 92 + #![allow( 93 + clippy::cast_lossless, 94 + clippy::cast_possible_truncation, 95 + clippy::checked_conversions, 96 + clippy::doc_markdown, 97 + clippy::elidable_lifetime_names, 98 + clippy::incompatible_msrv, 99 + clippy::items_after_statements, 100 + clippy::iter_without_into_iter, 101 + clippy::let_underscore_untyped, 102 + clippy::manual_assert, 103 + clippy::manual_range_contains, 104 + clippy::missing_panics_doc, 105 + clippy::missing_safety_doc, 106 + clippy::must_use_candidate, 107 + clippy::needless_doctest_main, 108 + clippy::needless_lifetimes, 109 + clippy::new_without_default, 110 + clippy::return_self_not_must_use, 111 + clippy::shadow_unrelated, 112 + clippy::trivially_copy_pass_by_ref, 113 + clippy::unnecessary_wraps, 114 + clippy::unused_self, 115 + clippy::used_underscore_binding, 116 + clippy::vec_init_then_push 117 + )] 118 + #![allow(unknown_lints, mismatched_lifetime_syntaxes)] 119 + 120 + #[cfg(all(procmacro2_semver_exempt, wrap_proc_macro, not(super_unstable)))] 121 + compile_error! {"\ 122 + Something is not right. If you've tried to turn on \ 123 + procmacro2_semver_exempt, you need to ensure that it \ 124 + is turned on for the compilation of the proc-macro2 \ 125 + build script as well. 126 + "} 127 + 128 + #[cfg(all( 129 + procmacro2_nightly_testing, 130 + feature = "proc-macro", 131 + not(proc_macro_span) 132 + ))] 133 + compile_error! {"\ 134 + Build script probe failed to compile. 135 + "} 136 + 137 + extern crate alloc; 138 + 139 + #[cfg(feature = "proc-macro")] 140 + extern crate proc_macro; 141 + 142 + mod marker; 143 + mod parse; 144 + mod probe; 145 + mod rcvec; 146 + 147 + #[cfg(wrap_proc_macro)] 148 + mod detection; 149 + 150 + // Public for proc_macro2::fallback::force() and unforce(), but those are quite 151 + // a niche use case so we omit it from rustdoc. 152 + #[doc(hidden)] 153 + pub mod fallback; 154 + 155 + pub mod extra; 156 + 157 + #[cfg(not(wrap_proc_macro))] 158 + use crate::fallback as imp; 159 + #[path = "wrapper.rs"] 160 + #[cfg(wrap_proc_macro)] 161 + mod imp; 162 + 163 + #[cfg(span_locations)] 164 + mod location; 165 + 166 + use crate::extra::DelimSpan; 167 + use crate::marker::{ProcMacroAutoTraits, MARKER}; 168 + use core::cmp::Ordering; 169 + use core::fmt::{self, Debug, Display}; 170 + use core::hash::{Hash, Hasher}; 171 + #[cfg(span_locations)] 172 + use core::ops::Range; 173 + use core::ops::RangeBounds; 174 + use core::str::FromStr; 175 + use std::error::Error; 176 + use std::ffi::CStr; 177 + #[cfg(span_locations)] 178 + use std::path::PathBuf; 179 + 180 + #[cfg(span_locations)] 181 + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] 182 + pub use crate::location::LineColumn; 183 + 184 + /// An abstract stream of tokens, or more concretely a sequence of token trees. 185 + /// 186 + /// This type provides interfaces for iterating over token trees and for 187 + /// collecting token trees into one stream. 188 + /// 189 + /// Token stream is both the input and output of `#[proc_macro]`, 190 + /// `#[proc_macro_attribute]` and `#[proc_macro_derive]` definitions. 191 + #[derive(Clone)] 192 + pub struct TokenStream { 193 + inner: imp::TokenStream, 194 + _marker: ProcMacroAutoTraits, 195 + } 196 + 197 + /// Error returned from `TokenStream::from_str`. 198 + pub struct LexError { 199 + inner: imp::LexError, 200 + _marker: ProcMacroAutoTraits, 201 + } 202 + 203 + impl TokenStream { 204 + fn _new(inner: imp::TokenStream) -> Self { 205 + TokenStream { 206 + inner, 207 + _marker: MARKER, 208 + } 209 + } 210 + 211 + fn _new_fallback(inner: fallback::TokenStream) -> Self { 212 + TokenStream { 213 + inner: imp::TokenStream::from(inner), 214 + _marker: MARKER, 215 + } 216 + } 217 + 218 + /// Returns an empty `TokenStream` containing no token trees. 219 + pub fn new() -> Self { 220 + TokenStream::_new(imp::TokenStream::new()) 221 + } 222 + 223 + /// Checks if this `TokenStream` is empty. 224 + pub fn is_empty(&self) -> bool { 225 + self.inner.is_empty() 226 + } 227 + } 228 + 229 + /// `TokenStream::default()` returns an empty stream, 230 + /// i.e. this is equivalent with `TokenStream::new()`. 231 + impl Default for TokenStream { 232 + fn default() -> Self { 233 + TokenStream::new() 234 + } 235 + } 236 + 237 + /// Attempts to break the string into tokens and parse those tokens into a token 238 + /// stream. 239 + /// 240 + /// May fail for a number of reasons, for example, if the string contains 241 + /// unbalanced delimiters or characters not existing in the language. 242 + /// 243 + /// NOTE: Some errors may cause panics instead of returning `LexError`. We 244 + /// reserve the right to change these errors into `LexError`s later. 245 + impl FromStr for TokenStream { 246 + type Err = LexError; 247 + 248 + fn from_str(src: &str) -> Result<TokenStream, LexError> { 249 + match imp::TokenStream::from_str_checked(src) { 250 + Ok(tokens) => Ok(TokenStream::_new(tokens)), 251 + Err(lex) => Err(LexError { 252 + inner: lex, 253 + _marker: MARKER, 254 + }), 255 + } 256 + } 257 + } 258 + 259 + #[cfg(feature = "proc-macro")] 260 + #[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))] 261 + impl From<proc_macro::TokenStream> for TokenStream { 262 + fn from(inner: proc_macro::TokenStream) -> Self { 263 + TokenStream::_new(imp::TokenStream::from(inner)) 264 + } 265 + } 266 + 267 + #[cfg(feature = "proc-macro")] 268 + #[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))] 269 + impl From<TokenStream> for proc_macro::TokenStream { 270 + fn from(inner: TokenStream) -> Self { 271 + proc_macro::TokenStream::from(inner.inner) 272 + } 273 + } 274 + 275 + impl From<TokenTree> for TokenStream { 276 + fn from(token: TokenTree) -> Self { 277 + TokenStream::_new(imp::TokenStream::from(token)) 278 + } 279 + } 280 + 281 + impl Extend<TokenTree> for TokenStream { 282 + fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I) { 283 + self.inner.extend(streams); 284 + } 285 + } 286 + 287 + impl Extend<TokenStream> for TokenStream { 288 + fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) { 289 + self.inner 290 + .extend(streams.into_iter().map(|stream| stream.inner)); 291 + } 292 + } 293 + 294 + /// Collects a number of token trees into a single stream. 295 + impl FromIterator<TokenTree> for TokenStream { 296 + fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self { 297 + TokenStream::_new(streams.into_iter().collect()) 298 + } 299 + } 300 + impl FromIterator<TokenStream> for TokenStream { 301 + fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self { 302 + TokenStream::_new(streams.into_iter().map(|i| i.inner).collect()) 303 + } 304 + } 305 + 306 + /// Prints the token stream as a string that is supposed to be losslessly 307 + /// convertible back into the same token stream (modulo spans), except for 308 + /// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative 309 + /// numeric literals. 310 + impl Display for TokenStream { 311 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 312 + Display::fmt(&self.inner, f) 313 + } 314 + } 315 + 316 + /// Prints token in a form convenient for debugging. 317 + impl Debug for TokenStream { 318 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 319 + Debug::fmt(&self.inner, f) 320 + } 321 + } 322 + 323 + impl LexError { 324 + pub fn span(&self) -> Span { 325 + Span::_new(self.inner.span()) 326 + } 327 + } 328 + 329 + impl Debug for LexError { 330 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 331 + Debug::fmt(&self.inner, f) 332 + } 333 + } 334 + 335 + impl Display for LexError { 336 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 337 + Display::fmt(&self.inner, f) 338 + } 339 + } 340 + 341 + impl Error for LexError {} 342 + 343 + /// A region of source code, along with macro expansion information. 344 + #[derive(Copy, Clone)] 345 + pub struct Span { 346 + inner: imp::Span, 347 + _marker: ProcMacroAutoTraits, 348 + } 349 + 350 + impl Span { 351 + fn _new(inner: imp::Span) -> Self { 352 + Span { 353 + inner, 354 + _marker: MARKER, 355 + } 356 + } 357 + 358 + fn _new_fallback(inner: fallback::Span) -> Self { 359 + Span { 360 + inner: imp::Span::from(inner), 361 + _marker: MARKER, 362 + } 363 + } 364 + 365 + /// The span of the invocation of the current procedural macro. 366 + /// 367 + /// Identifiers created with this span will be resolved as if they were 368 + /// written directly at the macro call location (call-site hygiene) and 369 + /// other code at the macro call site will be able to refer to them as well. 370 + pub fn call_site() -> Self { 371 + Span::_new(imp::Span::call_site()) 372 + } 373 + 374 + /// The span located at the invocation of the procedural macro, but with 375 + /// local variables, labels, and `$crate` resolved at the definition site 376 + /// of the macro. This is the same hygiene behavior as `macro_rules`. 377 + pub fn mixed_site() -> Self { 378 + Span::_new(imp::Span::mixed_site()) 379 + } 380 + 381 + /// A span that resolves at the macro definition site. 382 + /// 383 + /// This method is semver exempt and not exposed by default. 384 + #[cfg(procmacro2_semver_exempt)] 385 + #[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))] 386 + pub fn def_site() -> Self { 387 + Span::_new(imp::Span::def_site()) 388 + } 389 + 390 + /// Creates a new span with the same line/column information as `self` but 391 + /// that resolves symbols as though it were at `other`. 392 + pub fn resolved_at(&self, other: Span) -> Span { 393 + Span::_new(self.inner.resolved_at(other.inner)) 394 + } 395 + 396 + /// Creates a new span with the same name resolution behavior as `self` but 397 + /// with the line/column information of `other`. 398 + pub fn located_at(&self, other: Span) -> Span { 399 + Span::_new(self.inner.located_at(other.inner)) 400 + } 401 + 402 + /// Convert `proc_macro2::Span` to `proc_macro::Span`. 403 + /// 404 + /// This method is available when building with a nightly compiler, or when 405 + /// building with rustc 1.29+ *without* semver exempt features. 406 + /// 407 + /// # Panics 408 + /// 409 + /// Panics if called from outside of a procedural macro. Unlike 410 + /// `proc_macro2::Span`, the `proc_macro::Span` type can only exist within 411 + /// the context of a procedural macro invocation. 412 + #[cfg(wrap_proc_macro)] 413 + pub fn unwrap(self) -> proc_macro::Span { 414 + self.inner.unwrap() 415 + } 416 + 417 + // Soft deprecated. Please use Span::unwrap. 418 + #[cfg(wrap_proc_macro)] 419 + #[doc(hidden)] 420 + pub fn unstable(self) -> proc_macro::Span { 421 + self.unwrap() 422 + } 423 + 424 + /// Returns the span's byte position range in the source file. 425 + /// 426 + /// This method requires the `"span-locations"` feature to be enabled. 427 + /// 428 + /// When executing in a procedural macro context, the returned range is only 429 + /// accurate if compiled with a nightly toolchain. The stable toolchain does 430 + /// not have this information available. When executing outside of a 431 + /// procedural macro, such as main.rs or build.rs, the byte range is always 432 + /// accurate regardless of toolchain. 433 + #[cfg(span_locations)] 434 + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] 435 + pub fn byte_range(&self) -> Range<usize> { 436 + self.inner.byte_range() 437 + } 438 + 439 + /// Get the starting line/column in the source file for this span. 440 + /// 441 + /// This method requires the `"span-locations"` feature to be enabled. 442 + /// 443 + /// When executing in a procedural macro context, the returned line/column 444 + /// are only meaningful if compiled with a nightly toolchain. The stable 445 + /// toolchain does not have this information available. When executing 446 + /// outside of a procedural macro, such as main.rs or build.rs, the 447 + /// line/column are always meaningful regardless of toolchain. 448 + #[cfg(span_locations)] 449 + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] 450 + pub fn start(&self) -> LineColumn { 451 + self.inner.start() 452 + } 453 + 454 + /// Get the ending line/column in the source file for this span. 455 + /// 456 + /// This method requires the `"span-locations"` feature to be enabled. 457 + /// 458 + /// When executing in a procedural macro context, the returned line/column 459 + /// are only meaningful if compiled with a nightly toolchain. The stable 460 + /// toolchain does not have this information available. When executing 461 + /// outside of a procedural macro, such as main.rs or build.rs, the 462 + /// line/column are always meaningful regardless of toolchain. 463 + #[cfg(span_locations)] 464 + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] 465 + pub fn end(&self) -> LineColumn { 466 + self.inner.end() 467 + } 468 + 469 + /// The path to the source file in which this span occurs, for display 470 + /// purposes. 471 + /// 472 + /// This might not correspond to a valid file system path. It might be 473 + /// remapped, or might be an artificial path such as `"<macro expansion>"`. 474 + #[cfg(span_locations)] 475 + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] 476 + pub fn file(&self) -> String { 477 + self.inner.file() 478 + } 479 + 480 + /// The path to the source file in which this span occurs on disk. 481 + /// 482 + /// This is the actual path on disk. It is unaffected by path remapping. 483 + /// 484 + /// This path should not be embedded in the output of the macro; prefer 485 + /// `file()` instead. 486 + #[cfg(span_locations)] 487 + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] 488 + pub fn local_file(&self) -> Option<PathBuf> { 489 + self.inner.local_file() 490 + } 491 + 492 + /// Create a new span encompassing `self` and `other`. 493 + /// 494 + /// Returns `None` if `self` and `other` are from different files. 495 + /// 496 + /// Warning: the underlying [`proc_macro::Span::join`] method is 497 + /// nightly-only. When called from within a procedural macro not using a 498 + /// nightly compiler, this method will always return `None`. 499 + pub fn join(&self, other: Span) -> Option<Span> { 500 + self.inner.join(other.inner).map(Span::_new) 501 + } 502 + 503 + /// Compares two spans to see if they're equal. 504 + /// 505 + /// This method is semver exempt and not exposed by default. 506 + #[cfg(procmacro2_semver_exempt)] 507 + #[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))] 508 + pub fn eq(&self, other: &Span) -> bool { 509 + self.inner.eq(&other.inner) 510 + } 511 + 512 + /// Returns the source text behind a span. This preserves the original 513 + /// source code, including spaces and comments. It only returns a result if 514 + /// the span corresponds to real source code. 515 + /// 516 + /// Note: The observable result of a macro should only rely on the tokens 517 + /// and not on this source text. The result of this function is a best 518 + /// effort to be used for diagnostics only. 519 + pub fn source_text(&self) -> Option<String> { 520 + self.inner.source_text() 521 + } 522 + } 523 + 524 + /// Prints a span in a form convenient for debugging. 525 + impl Debug for Span { 526 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 527 + Debug::fmt(&self.inner, f) 528 + } 529 + } 530 + 531 + /// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`). 532 + #[derive(Clone)] 533 + pub enum TokenTree { 534 + /// A token stream surrounded by bracket delimiters. 535 + Group(Group), 536 + /// An identifier. 537 + Ident(Ident), 538 + /// A single punctuation character (`+`, `,`, `$`, etc.). 539 + Punct(Punct), 540 + /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc. 541 + Literal(Literal), 542 + } 543 + 544 + impl TokenTree { 545 + /// Returns the span of this tree, delegating to the `span` method of 546 + /// the contained token or a delimited stream. 547 + pub fn span(&self) -> Span { 548 + match self { 549 + TokenTree::Group(t) => t.span(), 550 + TokenTree::Ident(t) => t.span(), 551 + TokenTree::Punct(t) => t.span(), 552 + TokenTree::Literal(t) => t.span(), 553 + } 554 + } 555 + 556 + /// Configures the span for *only this token*. 557 + /// 558 + /// Note that if this token is a `Group` then this method will not configure 559 + /// the span of each of the internal tokens, this will simply delegate to 560 + /// the `set_span` method of each variant. 561 + pub fn set_span(&mut self, span: Span) { 562 + match self { 563 + TokenTree::Group(t) => t.set_span(span), 564 + TokenTree::Ident(t) => t.set_span(span), 565 + TokenTree::Punct(t) => t.set_span(span), 566 + TokenTree::Literal(t) => t.set_span(span), 567 + } 568 + } 569 + } 570 + 571 + impl From<Group> for TokenTree { 572 + fn from(g: Group) -> Self { 573 + TokenTree::Group(g) 574 + } 575 + } 576 + 577 + impl From<Ident> for TokenTree { 578 + fn from(g: Ident) -> Self { 579 + TokenTree::Ident(g) 580 + } 581 + } 582 + 583 + impl From<Punct> for TokenTree { 584 + fn from(g: Punct) -> Self { 585 + TokenTree::Punct(g) 586 + } 587 + } 588 + 589 + impl From<Literal> for TokenTree { 590 + fn from(g: Literal) -> Self { 591 + TokenTree::Literal(g) 592 + } 593 + } 594 + 595 + /// Prints the token tree as a string that is supposed to be losslessly 596 + /// convertible back into the same token tree (modulo spans), except for 597 + /// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative 598 + /// numeric literals. 599 + impl Display for TokenTree { 600 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 601 + match self { 602 + TokenTree::Group(t) => Display::fmt(t, f), 603 + TokenTree::Ident(t) => Display::fmt(t, f), 604 + TokenTree::Punct(t) => Display::fmt(t, f), 605 + TokenTree::Literal(t) => Display::fmt(t, f), 606 + } 607 + } 608 + } 609 + 610 + /// Prints token tree in a form convenient for debugging. 611 + impl Debug for TokenTree { 612 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 613 + // Each of these has the name in the struct type in the derived debug, 614 + // so don't bother with an extra layer of indirection 615 + match self { 616 + TokenTree::Group(t) => Debug::fmt(t, f), 617 + TokenTree::Ident(t) => { 618 + let mut debug = f.debug_struct("Ident"); 619 + debug.field("sym", &format_args!("{}", t)); 620 + imp::debug_span_field_if_nontrivial(&mut debug, t.span().inner); 621 + debug.finish() 622 + } 623 + TokenTree::Punct(t) => Debug::fmt(t, f), 624 + TokenTree::Literal(t) => Debug::fmt(t, f), 625 + } 626 + } 627 + } 628 + 629 + /// A delimited token stream. 630 + /// 631 + /// A `Group` internally contains a `TokenStream` which is surrounded by 632 + /// `Delimiter`s. 633 + #[derive(Clone)] 634 + pub struct Group { 635 + inner: imp::Group, 636 + } 637 + 638 + /// Describes how a sequence of token trees is delimited. 639 + #[derive(Copy, Clone, Debug, Eq, PartialEq)] 640 + pub enum Delimiter { 641 + /// `( ... )` 642 + Parenthesis, 643 + /// `{ ... }` 644 + Brace, 645 + /// `[ ... ]` 646 + Bracket, 647 + /// `∅ ... ∅` 648 + /// 649 + /// An invisible delimiter, that may, for example, appear around tokens 650 + /// coming from a "macro variable" `$var`. It is important to preserve 651 + /// operator priorities in cases like `$var * 3` where `$var` is `1 + 2`. 652 + /// Invisible delimiters may not survive roundtrip of a token stream through 653 + /// a string. 654 + /// 655 + /// <div class="warning"> 656 + /// 657 + /// Note: rustc currently can ignore the grouping of tokens delimited by `None` in the output 658 + /// of a proc_macro. Only `None`-delimited groups created by a macro_rules macro in the input 659 + /// of a proc_macro macro are preserved, and only in very specific circumstances. 660 + /// Any `None`-delimited groups (re)created by a proc_macro will therefore not preserve 661 + /// operator priorities as indicated above. The other `Delimiter` variants should be used 662 + /// instead in this context. This is a rustc bug. For details, see 663 + /// [rust-lang/rust#67062](https://github.com/rust-lang/rust/issues/67062). 664 + /// 665 + /// </div> 666 + None, 667 + } 668 + 669 + impl Group { 670 + fn _new(inner: imp::Group) -> Self { 671 + Group { inner } 672 + } 673 + 674 + fn _new_fallback(inner: fallback::Group) -> Self { 675 + Group { 676 + inner: imp::Group::from(inner), 677 + } 678 + } 679 + 680 + /// Creates a new `Group` with the given delimiter and token stream. 681 + /// 682 + /// This constructor will set the span for this group to 683 + /// `Span::call_site()`. To change the span you can use the `set_span` 684 + /// method below. 685 + pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { 686 + Group { 687 + inner: imp::Group::new(delimiter, stream.inner), 688 + } 689 + } 690 + 691 + /// Returns the punctuation used as the delimiter for this group: a set of 692 + /// parentheses, square brackets, or curly braces. 693 + pub fn delimiter(&self) -> Delimiter { 694 + self.inner.delimiter() 695 + } 696 + 697 + /// Returns the `TokenStream` of tokens that are delimited in this `Group`. 698 + /// 699 + /// Note that the returned token stream does not include the delimiter 700 + /// returned above. 701 + pub fn stream(&self) -> TokenStream { 702 + TokenStream::_new(self.inner.stream()) 703 + } 704 + 705 + /// Returns the span for the delimiters of this token stream, spanning the 706 + /// entire `Group`. 707 + /// 708 + /// ```text 709 + /// pub fn span(&self) -> Span { 710 + /// ^^^^^^^ 711 + /// ``` 712 + pub fn span(&self) -> Span { 713 + Span::_new(self.inner.span()) 714 + } 715 + 716 + /// Returns the span pointing to the opening delimiter of this group. 717 + /// 718 + /// ```text 719 + /// pub fn span_open(&self) -> Span { 720 + /// ^ 721 + /// ``` 722 + pub fn span_open(&self) -> Span { 723 + Span::_new(self.inner.span_open()) 724 + } 725 + 726 + /// Returns the span pointing to the closing delimiter of this group. 727 + /// 728 + /// ```text 729 + /// pub fn span_close(&self) -> Span { 730 + /// ^ 731 + /// ``` 732 + pub fn span_close(&self) -> Span { 733 + Span::_new(self.inner.span_close()) 734 + } 735 + 736 + /// Returns an object that holds this group's `span_open()` and 737 + /// `span_close()` together (in a more compact representation than holding 738 + /// those 2 spans individually). 739 + pub fn delim_span(&self) -> DelimSpan { 740 + DelimSpan::new(&self.inner) 741 + } 742 + 743 + /// Configures the span for this `Group`'s delimiters, but not its internal 744 + /// tokens. 745 + /// 746 + /// This method will **not** set the span of all the internal tokens spanned 747 + /// by this group, but rather it will only set the span of the delimiter 748 + /// tokens at the level of the `Group`. 749 + pub fn set_span(&mut self, span: Span) { 750 + self.inner.set_span(span.inner); 751 + } 752 + } 753 + 754 + /// Prints the group as a string that should be losslessly convertible back 755 + /// into the same group (modulo spans), except for possibly `TokenTree::Group`s 756 + /// with `Delimiter::None` delimiters. 757 + impl Display for Group { 758 + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 759 + Display::fmt(&self.inner, formatter) 760 + } 761 + } 762 + 763 + impl Debug for Group { 764 + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 765 + Debug::fmt(&self.inner, formatter) 766 + } 767 + } 768 + 769 + /// A `Punct` is a single punctuation character like `+`, `-` or `#`. 770 + /// 771 + /// Multicharacter operators like `+=` are represented as two instances of 772 + /// `Punct` with different forms of `Spacing` returned. 773 + #[derive(Clone)] 774 + pub struct Punct { 775 + ch: char, 776 + spacing: Spacing, 777 + span: Span, 778 + } 779 + 780 + /// Whether a `Punct` is followed immediately by another `Punct` or followed by 781 + /// another token or whitespace. 782 + #[derive(Copy, Clone, Debug, Eq, PartialEq)] 783 + pub enum Spacing { 784 + /// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`. 785 + Alone, 786 + /// E.g. `+` is `Joint` in `+=` or `'` is `Joint` in `'#`. 787 + /// 788 + /// Additionally, single quote `'` can join with identifiers to form 789 + /// lifetimes `'ident`. 790 + Joint, 791 + } 792 + 793 + impl Punct { 794 + /// Creates a new `Punct` from the given character and spacing. 795 + /// 796 + /// The `ch` argument must be a valid punctuation character permitted by the 797 + /// language, otherwise the function will panic. 798 + /// 799 + /// The returned `Punct` will have the default span of `Span::call_site()` 800 + /// which can be further configured with the `set_span` method below. 801 + pub fn new(ch: char, spacing: Spacing) -> Self { 802 + if let '!' | '#' | '$' | '%' | '&' | '\'' | '*' | '+' | ',' | '-' | '.' | '/' | ':' | ';' 803 + | '<' | '=' | '>' | '?' | '@' | '^' | '|' | '~' = ch 804 + { 805 + Punct { 806 + ch, 807 + spacing, 808 + span: Span::call_site(), 809 + } 810 + } else { 811 + panic!("unsupported proc macro punctuation character {:?}", ch); 812 + } 813 + } 814 + 815 + /// Returns the value of this punctuation character as `char`. 816 + pub fn as_char(&self) -> char { 817 + self.ch 818 + } 819 + 820 + /// Returns the spacing of this punctuation character, indicating whether 821 + /// it's immediately followed by another `Punct` in the token stream, so 822 + /// they can potentially be combined into a multicharacter operator 823 + /// (`Joint`), or it's followed by some other token or whitespace (`Alone`) 824 + /// so the operator has certainly ended. 825 + pub fn spacing(&self) -> Spacing { 826 + self.spacing 827 + } 828 + 829 + /// Returns the span for this punctuation character. 830 + pub fn span(&self) -> Span { 831 + self.span 832 + } 833 + 834 + /// Configure the span for this punctuation character. 835 + pub fn set_span(&mut self, span: Span) { 836 + self.span = span; 837 + } 838 + } 839 + 840 + /// Prints the punctuation character as a string that should be losslessly 841 + /// convertible back into the same character. 842 + impl Display for Punct { 843 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 844 + Display::fmt(&self.ch, f) 845 + } 846 + } 847 + 848 + impl Debug for Punct { 849 + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 850 + let mut debug = fmt.debug_struct("Punct"); 851 + debug.field("char", &self.ch); 852 + debug.field("spacing", &self.spacing); 853 + imp::debug_span_field_if_nontrivial(&mut debug, self.span.inner); 854 + debug.finish() 855 + } 856 + } 857 + 858 + /// A word of Rust code, which may be a keyword or legal variable name. 859 + /// 860 + /// An identifier consists of at least one Unicode code point, the first of 861 + /// which has the XID_Start property and the rest of which have the XID_Continue 862 + /// property. 863 + /// 864 + /// - The empty string is not an identifier. Use `Option<Ident>`. 865 + /// - A lifetime is not an identifier. Use `syn::Lifetime` instead. 866 + /// 867 + /// An identifier constructed with `Ident::new` is permitted to be a Rust 868 + /// keyword, though parsing one through its [`Parse`] implementation rejects 869 + /// Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the 870 + /// behaviour of `Ident::new`. 871 + /// 872 + /// [`Parse`]: https://docs.rs/syn/2.0/syn/parse/trait.Parse.html 873 + /// 874 + /// # Examples 875 + /// 876 + /// A new ident can be created from a string using the `Ident::new` function. 877 + /// A span must be provided explicitly which governs the name resolution 878 + /// behavior of the resulting identifier. 879 + /// 880 + /// ``` 881 + /// use proc_macro2::{Ident, Span}; 882 + /// 883 + /// fn main() { 884 + /// let call_ident = Ident::new("calligraphy", Span::call_site()); 885 + /// 886 + /// println!("{}", call_ident); 887 + /// } 888 + /// ``` 889 + /// 890 + /// An ident can be interpolated into a token stream using the `quote!` macro. 891 + /// 892 + /// ``` 893 + /// use proc_macro2::{Ident, Span}; 894 + /// use quote::quote; 895 + /// 896 + /// fn main() { 897 + /// let ident = Ident::new("demo", Span::call_site()); 898 + /// 899 + /// // Create a variable binding whose name is this ident. 900 + /// let expanded = quote! { let #ident = 10; }; 901 + /// 902 + /// // Create a variable binding with a slightly different name. 903 + /// let temp_ident = Ident::new(&format!("new_{}", ident), Span::call_site()); 904 + /// let expanded = quote! { let #temp_ident = 10; }; 905 + /// } 906 + /// ``` 907 + /// 908 + /// A string representation of the ident is available through the `to_string()` 909 + /// method. 910 + /// 911 + /// ``` 912 + /// # use proc_macro2::{Ident, Span}; 913 + /// # 914 + /// # let ident = Ident::new("another_identifier", Span::call_site()); 915 + /// # 916 + /// // Examine the ident as a string. 917 + /// let ident_string = ident.to_string(); 918 + /// if ident_string.len() > 60 { 919 + /// println!("Very long identifier: {}", ident_string) 920 + /// } 921 + /// ``` 922 + #[derive(Clone)] 923 + pub struct Ident { 924 + inner: imp::Ident, 925 + _marker: ProcMacroAutoTraits, 926 + } 927 + 928 + impl Ident { 929 + fn _new(inner: imp::Ident) -> Self { 930 + Ident { 931 + inner, 932 + _marker: MARKER, 933 + } 934 + } 935 + 936 + fn _new_fallback(inner: fallback::Ident) -> Self { 937 + Ident { 938 + inner: imp::Ident::from(inner), 939 + _marker: MARKER, 940 + } 941 + } 942 + 943 + /// Creates a new `Ident` with the given `string` as well as the specified 944 + /// `span`. 945 + /// 946 + /// The `string` argument must be a valid identifier permitted by the 947 + /// language, otherwise the function will panic. 948 + /// 949 + /// Note that `span`, currently in rustc, configures the hygiene information 950 + /// for this identifier. 951 + /// 952 + /// As of this time `Span::call_site()` explicitly opts-in to "call-site" 953 + /// hygiene meaning that identifiers created with this span will be resolved 954 + /// as if they were written directly at the location of the macro call, and 955 + /// other code at the macro call site will be able to refer to them as well. 956 + /// 957 + /// Later spans like `Span::def_site()` will allow to opt-in to 958 + /// "definition-site" hygiene meaning that identifiers created with this 959 + /// span will be resolved at the location of the macro definition and other 960 + /// code at the macro call site will not be able to refer to them. 961 + /// 962 + /// Due to the current importance of hygiene this constructor, unlike other 963 + /// tokens, requires a `Span` to be specified at construction. 964 + /// 965 + /// # Panics 966 + /// 967 + /// Panics if the input string is neither a keyword nor a legal variable 968 + /// name. If you are not sure whether the string contains an identifier and 969 + /// need to handle an error case, use 970 + /// <a href="https://docs.rs/syn/2.0/syn/fn.parse_str.html"><code 971 + /// style="padding-right:0;">syn::parse_str</code></a><code 972 + /// style="padding-left:0;">::&lt;Ident&gt;</code> 973 + /// rather than `Ident::new`. 974 + #[track_caller] 975 + pub fn new(string: &str, span: Span) -> Self { 976 + Ident::_new(imp::Ident::new_checked(string, span.inner)) 977 + } 978 + 979 + /// Same as `Ident::new`, but creates a raw identifier (`r#ident`). The 980 + /// `string` argument must be a valid identifier permitted by the language 981 + /// (including keywords, e.g. `fn`). Keywords which are usable in path 982 + /// segments (e.g. `self`, `super`) are not supported, and will cause a 983 + /// panic. 984 + #[track_caller] 985 + pub fn new_raw(string: &str, span: Span) -> Self { 986 + Ident::_new(imp::Ident::new_raw_checked(string, span.inner)) 987 + } 988 + 989 + /// Returns the span of this `Ident`. 990 + pub fn span(&self) -> Span { 991 + Span::_new(self.inner.span()) 992 + } 993 + 994 + /// Configures the span of this `Ident`, possibly changing its hygiene 995 + /// context. 996 + pub fn set_span(&mut self, span: Span) { 997 + self.inner.set_span(span.inner); 998 + } 999 + } 1000 + 1001 + impl PartialEq for Ident { 1002 + fn eq(&self, other: &Ident) -> bool { 1003 + self.inner == other.inner 1004 + } 1005 + } 1006 + 1007 + impl<T> PartialEq<T> for Ident 1008 + where 1009 + T: ?Sized + AsRef<str>, 1010 + { 1011 + fn eq(&self, other: &T) -> bool { 1012 + self.inner == other 1013 + } 1014 + } 1015 + 1016 + impl Eq for Ident {} 1017 + 1018 + impl PartialOrd for Ident { 1019 + fn partial_cmp(&self, other: &Ident) -> Option<Ordering> { 1020 + Some(self.cmp(other)) 1021 + } 1022 + } 1023 + 1024 + impl Ord for Ident { 1025 + fn cmp(&self, other: &Ident) -> Ordering { 1026 + self.to_string().cmp(&other.to_string()) 1027 + } 1028 + } 1029 + 1030 + impl Hash for Ident { 1031 + fn hash<H: Hasher>(&self, hasher: &mut H) { 1032 + self.to_string().hash(hasher); 1033 + } 1034 + } 1035 + 1036 + /// Prints the identifier as a string that should be losslessly convertible back 1037 + /// into the same identifier. 1038 + impl Display for Ident { 1039 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1040 + Display::fmt(&self.inner, f) 1041 + } 1042 + } 1043 + 1044 + impl Debug for Ident { 1045 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1046 + Debug::fmt(&self.inner, f) 1047 + } 1048 + } 1049 + 1050 + /// A literal string (`"hello"`), byte string (`b"hello"`), character (`'a'`), 1051 + /// byte character (`b'a'`), an integer or floating point number with or without 1052 + /// a suffix (`1`, `1u8`, `2.3`, `2.3f32`). 1053 + /// 1054 + /// Boolean literals like `true` and `false` do not belong here, they are 1055 + /// `Ident`s. 1056 + #[derive(Clone)] 1057 + pub struct Literal { 1058 + inner: imp::Literal, 1059 + _marker: ProcMacroAutoTraits, 1060 + } 1061 + 1062 + macro_rules! suffixed_int_literals { 1063 + ($($name:ident => $kind:ident,)*) => ($( 1064 + /// Creates a new suffixed integer literal with the specified value. 1065 + /// 1066 + /// This function will create an integer like `1u32` where the integer 1067 + /// value specified is the first part of the token and the integral is 1068 + /// also suffixed at the end. Literals created from negative numbers may 1069 + /// not survive roundtrips through `TokenStream` or strings and may be 1070 + /// broken into two tokens (`-` and positive literal). 1071 + /// 1072 + /// Literals created through this method have the `Span::call_site()` 1073 + /// span by default, which can be configured with the `set_span` method 1074 + /// below. 1075 + pub fn $name(n: $kind) -> Literal { 1076 + Literal::_new(imp::Literal::$name(n)) 1077 + } 1078 + )*) 1079 + } 1080 + 1081 + macro_rules! unsuffixed_int_literals { 1082 + ($($name:ident => $kind:ident,)*) => ($( 1083 + /// Creates a new unsuffixed integer literal with the specified value. 1084 + /// 1085 + /// This function will create an integer like `1` where the integer 1086 + /// value specified is the first part of the token. No suffix is 1087 + /// specified on this token, meaning that invocations like 1088 + /// `Literal::i8_unsuffixed(1)` are equivalent to 1089 + /// `Literal::u32_unsuffixed(1)`. Literals created from negative numbers 1090 + /// may not survive roundtrips through `TokenStream` or strings and may 1091 + /// be broken into two tokens (`-` and positive literal). 1092 + /// 1093 + /// Literals created through this method have the `Span::call_site()` 1094 + /// span by default, which can be configured with the `set_span` method 1095 + /// below. 1096 + pub fn $name(n: $kind) -> Literal { 1097 + Literal::_new(imp::Literal::$name(n)) 1098 + } 1099 + )*) 1100 + } 1101 + 1102 + impl Literal { 1103 + fn _new(inner: imp::Literal) -> Self { 1104 + Literal { 1105 + inner, 1106 + _marker: MARKER, 1107 + } 1108 + } 1109 + 1110 + fn _new_fallback(inner: fallback::Literal) -> Self { 1111 + Literal { 1112 + inner: imp::Literal::from(inner), 1113 + _marker: MARKER, 1114 + } 1115 + } 1116 + 1117 + suffixed_int_literals! { 1118 + u8_suffixed => u8, 1119 + u16_suffixed => u16, 1120 + u32_suffixed => u32, 1121 + u64_suffixed => u64, 1122 + u128_suffixed => u128, 1123 + usize_suffixed => usize, 1124 + i8_suffixed => i8, 1125 + i16_suffixed => i16, 1126 + i32_suffixed => i32, 1127 + i64_suffixed => i64, 1128 + i128_suffixed => i128, 1129 + isize_suffixed => isize, 1130 + } 1131 + 1132 + unsuffixed_int_literals! { 1133 + u8_unsuffixed => u8, 1134 + u16_unsuffixed => u16, 1135 + u32_unsuffixed => u32, 1136 + u64_unsuffixed => u64, 1137 + u128_unsuffixed => u128, 1138 + usize_unsuffixed => usize, 1139 + i8_unsuffixed => i8, 1140 + i16_unsuffixed => i16, 1141 + i32_unsuffixed => i32, 1142 + i64_unsuffixed => i64, 1143 + i128_unsuffixed => i128, 1144 + isize_unsuffixed => isize, 1145 + } 1146 + 1147 + /// Creates a new unsuffixed floating-point literal. 1148 + /// 1149 + /// This constructor is similar to those like `Literal::i8_unsuffixed` where 1150 + /// the float's value is emitted directly into the token but no suffix is 1151 + /// used, so it may be inferred to be a `f64` later in the compiler. 1152 + /// Literals created from negative numbers may not survive round-trips 1153 + /// through `TokenStream` or strings and may be broken into two tokens (`-` 1154 + /// and positive literal). 1155 + /// 1156 + /// # Panics 1157 + /// 1158 + /// This function requires that the specified float is finite, for example 1159 + /// if it is infinity or NaN this function will panic. 1160 + pub fn f64_unsuffixed(f: f64) -> Literal { 1161 + assert!(f.is_finite()); 1162 + Literal::_new(imp::Literal::f64_unsuffixed(f)) 1163 + } 1164 + 1165 + /// Creates a new suffixed floating-point literal. 1166 + /// 1167 + /// This constructor will create a literal like `1.0f64` where the value 1168 + /// specified is the preceding part of the token and `f64` is the suffix of 1169 + /// the token. This token will always be inferred to be an `f64` in the 1170 + /// compiler. Literals created from negative numbers may not survive 1171 + /// round-trips through `TokenStream` or strings and may be broken into two 1172 + /// tokens (`-` and positive literal). 1173 + /// 1174 + /// # Panics 1175 + /// 1176 + /// This function requires that the specified float is finite, for example 1177 + /// if it is infinity or NaN this function will panic. 1178 + pub fn f64_suffixed(f: f64) -> Literal { 1179 + assert!(f.is_finite()); 1180 + Literal::_new(imp::Literal::f64_suffixed(f)) 1181 + } 1182 + 1183 + /// Creates a new unsuffixed floating-point literal. 1184 + /// 1185 + /// This constructor is similar to those like `Literal::i8_unsuffixed` where 1186 + /// the float's value is emitted directly into the token but no suffix is 1187 + /// used, so it may be inferred to be a `f64` later in the compiler. 1188 + /// Literals created from negative numbers may not survive round-trips 1189 + /// through `TokenStream` or strings and may be broken into two tokens (`-` 1190 + /// and positive literal). 1191 + /// 1192 + /// # Panics 1193 + /// 1194 + /// This function requires that the specified float is finite, for example 1195 + /// if it is infinity or NaN this function will panic. 1196 + pub fn f32_unsuffixed(f: f32) -> Literal { 1197 + assert!(f.is_finite()); 1198 + Literal::_new(imp::Literal::f32_unsuffixed(f)) 1199 + } 1200 + 1201 + /// Creates a new suffixed floating-point literal. 1202 + /// 1203 + /// This constructor will create a literal like `1.0f32` where the value 1204 + /// specified is the preceding part of the token and `f32` is the suffix of 1205 + /// the token. This token will always be inferred to be an `f32` in the 1206 + /// compiler. Literals created from negative numbers may not survive 1207 + /// round-trips through `TokenStream` or strings and may be broken into two 1208 + /// tokens (`-` and positive literal). 1209 + /// 1210 + /// # Panics 1211 + /// 1212 + /// This function requires that the specified float is finite, for example 1213 + /// if it is infinity or NaN this function will panic. 1214 + pub fn f32_suffixed(f: f32) -> Literal { 1215 + assert!(f.is_finite()); 1216 + Literal::_new(imp::Literal::f32_suffixed(f)) 1217 + } 1218 + 1219 + /// String literal. 1220 + pub fn string(string: &str) -> Literal { 1221 + Literal::_new(imp::Literal::string(string)) 1222 + } 1223 + 1224 + /// Character literal. 1225 + pub fn character(ch: char) -> Literal { 1226 + Literal::_new(imp::Literal::character(ch)) 1227 + } 1228 + 1229 + /// Byte character literal. 1230 + pub fn byte_character(byte: u8) -> Literal { 1231 + Literal::_new(imp::Literal::byte_character(byte)) 1232 + } 1233 + 1234 + /// Byte string literal. 1235 + pub fn byte_string(bytes: &[u8]) -> Literal { 1236 + Literal::_new(imp::Literal::byte_string(bytes)) 1237 + } 1238 + 1239 + /// C string literal. 1240 + pub fn c_string(string: &CStr) -> Literal { 1241 + Literal::_new(imp::Literal::c_string(string)) 1242 + } 1243 + 1244 + /// Returns the span encompassing this literal. 1245 + pub fn span(&self) -> Span { 1246 + Span::_new(self.inner.span()) 1247 + } 1248 + 1249 + /// Configures the span associated for this literal. 1250 + pub fn set_span(&mut self, span: Span) { 1251 + self.inner.set_span(span.inner); 1252 + } 1253 + 1254 + /// Returns a `Span` that is a subset of `self.span()` containing only 1255 + /// the source bytes in range `range`. Returns `None` if the would-be 1256 + /// trimmed span is outside the bounds of `self`. 1257 + /// 1258 + /// Warning: the underlying [`proc_macro::Literal::subspan`] method is 1259 + /// nightly-only. When called from within a procedural macro not using a 1260 + /// nightly compiler, this method will always return `None`. 1261 + pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> { 1262 + self.inner.subspan(range).map(Span::_new) 1263 + } 1264 + 1265 + // Intended for the `quote!` macro to use when constructing a proc-macro2 1266 + // token out of a macro_rules $:literal token, which is already known to be 1267 + // a valid literal. This avoids reparsing/validating the literal's string 1268 + // representation. This is not public API other than for quote. 1269 + #[doc(hidden)] 1270 + pub unsafe fn from_str_unchecked(repr: &str) -> Self { 1271 + Literal::_new(unsafe { imp::Literal::from_str_unchecked(repr) }) 1272 + } 1273 + } 1274 + 1275 + impl FromStr for Literal { 1276 + type Err = LexError; 1277 + 1278 + fn from_str(repr: &str) -> Result<Self, LexError> { 1279 + match imp::Literal::from_str_checked(repr) { 1280 + Ok(lit) => Ok(Literal::_new(lit)), 1281 + Err(lex) => Err(LexError { 1282 + inner: lex, 1283 + _marker: MARKER, 1284 + }), 1285 + } 1286 + } 1287 + } 1288 + 1289 + impl Debug for Literal { 1290 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1291 + Debug::fmt(&self.inner, f) 1292 + } 1293 + } 1294 + 1295 + impl Display for Literal { 1296 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1297 + Display::fmt(&self.inner, f) 1298 + } 1299 + } 1300 + 1301 + /// Public implementation details for the `TokenStream` type, such as iterators. 1302 + pub mod token_stream { 1303 + use crate::marker::{ProcMacroAutoTraits, MARKER}; 1304 + use crate::{imp, TokenTree}; 1305 + use core::fmt::{self, Debug}; 1306 + 1307 + pub use crate::TokenStream; 1308 + 1309 + /// An iterator over `TokenStream`'s `TokenTree`s. 1310 + /// 1311 + /// The iteration is "shallow", e.g. the iterator doesn't recurse into 1312 + /// delimited groups, and returns whole groups as token trees. 1313 + #[derive(Clone)] 1314 + pub struct IntoIter { 1315 + inner: imp::TokenTreeIter, 1316 + _marker: ProcMacroAutoTraits, 1317 + } 1318 + 1319 + impl Iterator for IntoIter { 1320 + type Item = TokenTree; 1321 + 1322 + fn next(&mut self) -> Option<TokenTree> { 1323 + self.inner.next() 1324 + } 1325 + 1326 + fn size_hint(&self) -> (usize, Option<usize>) { 1327 + self.inner.size_hint() 1328 + } 1329 + } 1330 + 1331 + impl Debug for IntoIter { 1332 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1333 + f.write_str("TokenStream ")?; 1334 + f.debug_list().entries(self.clone()).finish() 1335 + } 1336 + } 1337 + 1338 + impl IntoIterator for TokenStream { 1339 + type Item = TokenTree; 1340 + type IntoIter = IntoIter; 1341 + 1342 + fn into_iter(self) -> IntoIter { 1343 + IntoIter { 1344 + inner: self.inner.into_iter(), 1345 + _marker: MARKER, 1346 + } 1347 + } 1348 + } 1349 + }
+29
rust/proc-macro2/location.rs
··· 1 + use core::cmp::Ordering; 2 + 3 + /// A line-column pair representing the start or end of a `Span`. 4 + /// 5 + /// This type is semver exempt and not exposed by default. 6 + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] 7 + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] 8 + pub struct LineColumn { 9 + /// The 1-indexed line in the source file on which the span starts or ends 10 + /// (inclusive). 11 + pub line: usize, 12 + /// The 0-indexed column (in UTF-8 characters) in the source file on which 13 + /// the span starts or ends (inclusive). 14 + pub column: usize, 15 + } 16 + 17 + impl Ord for LineColumn { 18 + fn cmp(&self, other: &Self) -> Ordering { 19 + self.line 20 + .cmp(&other.line) 21 + .then(self.column.cmp(&other.column)) 22 + } 23 + } 24 + 25 + impl PartialOrd for LineColumn { 26 + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { 27 + Some(self.cmp(other)) 28 + } 29 + }
+17
rust/proc-macro2/marker.rs
··· 1 + use alloc::rc::Rc; 2 + use core::marker::PhantomData; 3 + use core::panic::{RefUnwindSafe, UnwindSafe}; 4 + 5 + // Zero sized marker with the correct set of autotrait impls we want all proc 6 + // macro types to have. 7 + #[derive(Copy, Clone)] 8 + #[cfg_attr( 9 + all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)), 10 + derive(PartialEq, Eq) 11 + )] 12 + pub(crate) struct ProcMacroAutoTraits(PhantomData<Rc<()>>); 13 + 14 + pub(crate) const MARKER: ProcMacroAutoTraits = ProcMacroAutoTraits(PhantomData); 15 + 16 + impl UnwindSafe for ProcMacroAutoTraits {} 17 + impl RefUnwindSafe for ProcMacroAutoTraits {}
+995
rust/proc-macro2/parse.rs
··· 1 + use crate::fallback::{ 2 + self, is_ident_continue, is_ident_start, Group, Ident, LexError, Literal, Span, TokenStream, 3 + TokenStreamBuilder, 4 + }; 5 + use crate::{Delimiter, Punct, Spacing, TokenTree}; 6 + use core::char; 7 + use core::str::{Bytes, CharIndices, Chars}; 8 + 9 + #[derive(Copy, Clone, Eq, PartialEq)] 10 + pub(crate) struct Cursor<'a> { 11 + pub(crate) rest: &'a str, 12 + #[cfg(span_locations)] 13 + pub(crate) off: u32, 14 + } 15 + 16 + impl<'a> Cursor<'a> { 17 + pub(crate) fn advance(&self, bytes: usize) -> Cursor<'a> { 18 + let (_front, rest) = self.rest.split_at(bytes); 19 + Cursor { 20 + rest, 21 + #[cfg(span_locations)] 22 + off: self.off + _front.chars().count() as u32, 23 + } 24 + } 25 + 26 + pub(crate) fn starts_with(&self, s: &str) -> bool { 27 + self.rest.starts_with(s) 28 + } 29 + 30 + pub(crate) fn starts_with_char(&self, ch: char) -> bool { 31 + self.rest.starts_with(ch) 32 + } 33 + 34 + pub(crate) fn starts_with_fn<Pattern>(&self, f: Pattern) -> bool 35 + where 36 + Pattern: FnMut(char) -> bool, 37 + { 38 + self.rest.starts_with(f) 39 + } 40 + 41 + pub(crate) fn is_empty(&self) -> bool { 42 + self.rest.is_empty() 43 + } 44 + 45 + fn len(&self) -> usize { 46 + self.rest.len() 47 + } 48 + 49 + fn as_bytes(&self) -> &'a [u8] { 50 + self.rest.as_bytes() 51 + } 52 + 53 + fn bytes(&self) -> Bytes<'a> { 54 + self.rest.bytes() 55 + } 56 + 57 + fn chars(&self) -> Chars<'a> { 58 + self.rest.chars() 59 + } 60 + 61 + fn char_indices(&self) -> CharIndices<'a> { 62 + self.rest.char_indices() 63 + } 64 + 65 + fn parse(&self, tag: &str) -> Result<Cursor<'a>, Reject> { 66 + if self.starts_with(tag) { 67 + Ok(self.advance(tag.len())) 68 + } else { 69 + Err(Reject) 70 + } 71 + } 72 + } 73 + 74 + pub(crate) struct Reject; 75 + type PResult<'a, O> = Result<(Cursor<'a>, O), Reject>; 76 + 77 + fn skip_whitespace(input: Cursor) -> Cursor { 78 + let mut s = input; 79 + 80 + while !s.is_empty() { 81 + let byte = s.as_bytes()[0]; 82 + if byte == b'/' { 83 + if s.starts_with("//") 84 + && (!s.starts_with("///") || s.starts_with("////")) 85 + && !s.starts_with("//!") 86 + { 87 + let (cursor, _) = take_until_newline_or_eof(s); 88 + s = cursor; 89 + continue; 90 + } else if s.starts_with("/**/") { 91 + s = s.advance(4); 92 + continue; 93 + } else if s.starts_with("/*") 94 + && (!s.starts_with("/**") || s.starts_with("/***")) 95 + && !s.starts_with("/*!") 96 + { 97 + match block_comment(s) { 98 + Ok((rest, _)) => { 99 + s = rest; 100 + continue; 101 + } 102 + Err(Reject) => return s, 103 + } 104 + } 105 + } 106 + match byte { 107 + b' ' | 0x09..=0x0d => { 108 + s = s.advance(1); 109 + continue; 110 + } 111 + b if b.is_ascii() => {} 112 + _ => { 113 + let ch = s.chars().next().unwrap(); 114 + if is_whitespace(ch) { 115 + s = s.advance(ch.len_utf8()); 116 + continue; 117 + } 118 + } 119 + } 120 + return s; 121 + } 122 + s 123 + } 124 + 125 + fn block_comment(input: Cursor) -> PResult<&str> { 126 + if !input.starts_with("/*") { 127 + return Err(Reject); 128 + } 129 + 130 + let mut depth = 0usize; 131 + let bytes = input.as_bytes(); 132 + let mut i = 0usize; 133 + let upper = bytes.len() - 1; 134 + 135 + while i < upper { 136 + if bytes[i] == b'/' && bytes[i + 1] == b'*' { 137 + depth += 1; 138 + i += 1; // eat '*' 139 + } else if bytes[i] == b'*' && bytes[i + 1] == b'/' { 140 + depth -= 1; 141 + if depth == 0 { 142 + return Ok((input.advance(i + 2), &input.rest[..i + 2])); 143 + } 144 + i += 1; // eat '/' 145 + } 146 + i += 1; 147 + } 148 + 149 + Err(Reject) 150 + } 151 + 152 + fn is_whitespace(ch: char) -> bool { 153 + // Rust treats left-to-right mark and right-to-left mark as whitespace 154 + ch.is_whitespace() || ch == '\u{200e}' || ch == '\u{200f}' 155 + } 156 + 157 + fn word_break(input: Cursor) -> Result<Cursor, Reject> { 158 + match input.chars().next() { 159 + Some(ch) if is_ident_continue(ch) => Err(Reject), 160 + Some(_) | None => Ok(input), 161 + } 162 + } 163 + 164 + // Rustc's representation of a macro expansion error in expression position or 165 + // type position. 166 + const ERROR: &str = "(/*ERROR*/)"; 167 + 168 + pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> { 169 + let mut trees = TokenStreamBuilder::new(); 170 + let mut stack = Vec::new(); 171 + 172 + loop { 173 + input = skip_whitespace(input); 174 + 175 + if let Ok((rest, ())) = doc_comment(input, &mut trees) { 176 + input = rest; 177 + continue; 178 + } 179 + 180 + #[cfg(span_locations)] 181 + let lo = input.off; 182 + 183 + let first = match input.bytes().next() { 184 + Some(first) => first, 185 + None => match stack.last() { 186 + None => return Ok(trees.build()), 187 + #[cfg(span_locations)] 188 + Some((lo, _frame)) => { 189 + return Err(LexError { 190 + span: Span { lo: *lo, hi: *lo }, 191 + }) 192 + } 193 + #[cfg(not(span_locations))] 194 + Some(_frame) => return Err(LexError { span: Span {} }), 195 + }, 196 + }; 197 + 198 + if let Some(open_delimiter) = match first { 199 + b'(' if !input.starts_with(ERROR) => Some(Delimiter::Parenthesis), 200 + b'[' => Some(Delimiter::Bracket), 201 + b'{' => Some(Delimiter::Brace), 202 + _ => None, 203 + } { 204 + input = input.advance(1); 205 + let frame = (open_delimiter, trees); 206 + #[cfg(span_locations)] 207 + let frame = (lo, frame); 208 + stack.push(frame); 209 + trees = TokenStreamBuilder::new(); 210 + } else if let Some(close_delimiter) = match first { 211 + b')' => Some(Delimiter::Parenthesis), 212 + b']' => Some(Delimiter::Bracket), 213 + b'}' => Some(Delimiter::Brace), 214 + _ => None, 215 + } { 216 + let frame = match stack.pop() { 217 + Some(frame) => frame, 218 + None => return Err(lex_error(input)), 219 + }; 220 + #[cfg(span_locations)] 221 + let (lo, frame) = frame; 222 + let (open_delimiter, outer) = frame; 223 + if open_delimiter != close_delimiter { 224 + return Err(lex_error(input)); 225 + } 226 + input = input.advance(1); 227 + let mut g = Group::new(open_delimiter, trees.build()); 228 + g.set_span(Span { 229 + #[cfg(span_locations)] 230 + lo, 231 + #[cfg(span_locations)] 232 + hi: input.off, 233 + }); 234 + trees = outer; 235 + trees.push_token_from_parser(TokenTree::Group(crate::Group::_new_fallback(g))); 236 + } else { 237 + let (rest, mut tt) = match leaf_token(input) { 238 + Ok((rest, tt)) => (rest, tt), 239 + Err(Reject) => return Err(lex_error(input)), 240 + }; 241 + tt.set_span(crate::Span::_new_fallback(Span { 242 + #[cfg(span_locations)] 243 + lo, 244 + #[cfg(span_locations)] 245 + hi: rest.off, 246 + })); 247 + trees.push_token_from_parser(tt); 248 + input = rest; 249 + } 250 + } 251 + } 252 + 253 + fn lex_error(cursor: Cursor) -> LexError { 254 + #[cfg(not(span_locations))] 255 + let _ = cursor; 256 + LexError { 257 + span: Span { 258 + #[cfg(span_locations)] 259 + lo: cursor.off, 260 + #[cfg(span_locations)] 261 + hi: cursor.off, 262 + }, 263 + } 264 + } 265 + 266 + fn leaf_token(input: Cursor) -> PResult<TokenTree> { 267 + if let Ok((input, l)) = literal(input) { 268 + // must be parsed before ident 269 + Ok((input, TokenTree::Literal(crate::Literal::_new_fallback(l)))) 270 + } else if let Ok((input, p)) = punct(input) { 271 + Ok((input, TokenTree::Punct(p))) 272 + } else if let Ok((input, i)) = ident(input) { 273 + Ok((input, TokenTree::Ident(i))) 274 + } else if input.starts_with(ERROR) { 275 + let rest = input.advance(ERROR.len()); 276 + let repr = crate::Literal::_new_fallback(Literal::_new(ERROR.to_owned())); 277 + Ok((rest, TokenTree::Literal(repr))) 278 + } else { 279 + Err(Reject) 280 + } 281 + } 282 + 283 + fn ident(input: Cursor) -> PResult<crate::Ident> { 284 + if [ 285 + "r\"", "r#\"", "r##", "b\"", "b\'", "br\"", "br#", "c\"", "cr\"", "cr#", 286 + ] 287 + .iter() 288 + .any(|prefix| input.starts_with(prefix)) 289 + { 290 + Err(Reject) 291 + } else { 292 + ident_any(input) 293 + } 294 + } 295 + 296 + fn ident_any(input: Cursor) -> PResult<crate::Ident> { 297 + let raw = input.starts_with("r#"); 298 + let rest = input.advance((raw as usize) << 1); 299 + 300 + let (rest, sym) = ident_not_raw(rest)?; 301 + 302 + if !raw { 303 + let ident = 304 + crate::Ident::_new_fallback(Ident::new_unchecked(sym, fallback::Span::call_site())); 305 + return Ok((rest, ident)); 306 + } 307 + 308 + match sym { 309 + "_" | "super" | "self" | "Self" | "crate" => return Err(Reject), 310 + _ => {} 311 + } 312 + 313 + let ident = 314 + crate::Ident::_new_fallback(Ident::new_raw_unchecked(sym, fallback::Span::call_site())); 315 + Ok((rest, ident)) 316 + } 317 + 318 + fn ident_not_raw(input: Cursor) -> PResult<&str> { 319 + let mut chars = input.char_indices(); 320 + 321 + match chars.next() { 322 + Some((_, ch)) if is_ident_start(ch) => {} 323 + _ => return Err(Reject), 324 + } 325 + 326 + let mut end = input.len(); 327 + for (i, ch) in chars { 328 + if !is_ident_continue(ch) { 329 + end = i; 330 + break; 331 + } 332 + } 333 + 334 + Ok((input.advance(end), &input.rest[..end])) 335 + } 336 + 337 + pub(crate) fn literal(input: Cursor) -> PResult<Literal> { 338 + let rest = literal_nocapture(input)?; 339 + let end = input.len() - rest.len(); 340 + Ok((rest, Literal::_new(input.rest[..end].to_string()))) 341 + } 342 + 343 + fn literal_nocapture(input: Cursor) -> Result<Cursor, Reject> { 344 + if let Ok(ok) = string(input) { 345 + Ok(ok) 346 + } else if let Ok(ok) = byte_string(input) { 347 + Ok(ok) 348 + } else if let Ok(ok) = c_string(input) { 349 + Ok(ok) 350 + } else if let Ok(ok) = byte(input) { 351 + Ok(ok) 352 + } else if let Ok(ok) = character(input) { 353 + Ok(ok) 354 + } else if let Ok(ok) = float(input) { 355 + Ok(ok) 356 + } else if let Ok(ok) = int(input) { 357 + Ok(ok) 358 + } else { 359 + Err(Reject) 360 + } 361 + } 362 + 363 + fn literal_suffix(input: Cursor) -> Cursor { 364 + match ident_not_raw(input) { 365 + Ok((input, _)) => input, 366 + Err(Reject) => input, 367 + } 368 + } 369 + 370 + fn string(input: Cursor) -> Result<Cursor, Reject> { 371 + if let Ok(input) = input.parse("\"") { 372 + cooked_string(input) 373 + } else if let Ok(input) = input.parse("r") { 374 + raw_string(input) 375 + } else { 376 + Err(Reject) 377 + } 378 + } 379 + 380 + fn cooked_string(mut input: Cursor) -> Result<Cursor, Reject> { 381 + let mut chars = input.char_indices(); 382 + 383 + while let Some((i, ch)) = chars.next() { 384 + match ch { 385 + '"' => { 386 + let input = input.advance(i + 1); 387 + return Ok(literal_suffix(input)); 388 + } 389 + '\r' => match chars.next() { 390 + Some((_, '\n')) => {} 391 + _ => break, 392 + }, 393 + '\\' => match chars.next() { 394 + Some((_, 'x')) => { 395 + backslash_x_char(&mut chars)?; 396 + } 397 + Some((_, 'n' | 'r' | 't' | '\\' | '\'' | '"' | '0')) => {} 398 + Some((_, 'u')) => { 399 + backslash_u(&mut chars)?; 400 + } 401 + Some((newline, ch @ ('\n' | '\r'))) => { 402 + input = input.advance(newline + 1); 403 + trailing_backslash(&mut input, ch as u8)?; 404 + chars = input.char_indices(); 405 + } 406 + _ => break, 407 + }, 408 + _ch => {} 409 + } 410 + } 411 + Err(Reject) 412 + } 413 + 414 + fn raw_string(input: Cursor) -> Result<Cursor, Reject> { 415 + let (input, delimiter) = delimiter_of_raw_string(input)?; 416 + let mut bytes = input.bytes().enumerate(); 417 + while let Some((i, byte)) = bytes.next() { 418 + match byte { 419 + b'"' if input.rest[i + 1..].starts_with(delimiter) => { 420 + let rest = input.advance(i + 1 + delimiter.len()); 421 + return Ok(literal_suffix(rest)); 422 + } 423 + b'\r' => match bytes.next() { 424 + Some((_, b'\n')) => {} 425 + _ => break, 426 + }, 427 + _ => {} 428 + } 429 + } 430 + Err(Reject) 431 + } 432 + 433 + fn byte_string(input: Cursor) -> Result<Cursor, Reject> { 434 + if let Ok(input) = input.parse("b\"") { 435 + cooked_byte_string(input) 436 + } else if let Ok(input) = input.parse("br") { 437 + raw_byte_string(input) 438 + } else { 439 + Err(Reject) 440 + } 441 + } 442 + 443 + fn cooked_byte_string(mut input: Cursor) -> Result<Cursor, Reject> { 444 + let mut bytes = input.bytes().enumerate(); 445 + while let Some((offset, b)) = bytes.next() { 446 + match b { 447 + b'"' => { 448 + let input = input.advance(offset + 1); 449 + return Ok(literal_suffix(input)); 450 + } 451 + b'\r' => match bytes.next() { 452 + Some((_, b'\n')) => {} 453 + _ => break, 454 + }, 455 + b'\\' => match bytes.next() { 456 + Some((_, b'x')) => { 457 + backslash_x_byte(&mut bytes)?; 458 + } 459 + Some((_, b'n' | b'r' | b't' | b'\\' | b'0' | b'\'' | b'"')) => {} 460 + Some((newline, b @ (b'\n' | b'\r'))) => { 461 + input = input.advance(newline + 1); 462 + trailing_backslash(&mut input, b)?; 463 + bytes = input.bytes().enumerate(); 464 + } 465 + _ => break, 466 + }, 467 + b if b.is_ascii() => {} 468 + _ => break, 469 + } 470 + } 471 + Err(Reject) 472 + } 473 + 474 + fn delimiter_of_raw_string(input: Cursor) -> PResult<&str> { 475 + for (i, byte) in input.bytes().enumerate() { 476 + match byte { 477 + b'"' => { 478 + if i > 255 { 479 + // https://github.com/rust-lang/rust/pull/95251 480 + return Err(Reject); 481 + } 482 + return Ok((input.advance(i + 1), &input.rest[..i])); 483 + } 484 + b'#' => {} 485 + _ => break, 486 + } 487 + } 488 + Err(Reject) 489 + } 490 + 491 + fn raw_byte_string(input: Cursor) -> Result<Cursor, Reject> { 492 + let (input, delimiter) = delimiter_of_raw_string(input)?; 493 + let mut bytes = input.bytes().enumerate(); 494 + while let Some((i, byte)) = bytes.next() { 495 + match byte { 496 + b'"' if input.rest[i + 1..].starts_with(delimiter) => { 497 + let rest = input.advance(i + 1 + delimiter.len()); 498 + return Ok(literal_suffix(rest)); 499 + } 500 + b'\r' => match bytes.next() { 501 + Some((_, b'\n')) => {} 502 + _ => break, 503 + }, 504 + other => { 505 + if !other.is_ascii() { 506 + break; 507 + } 508 + } 509 + } 510 + } 511 + Err(Reject) 512 + } 513 + 514 + fn c_string(input: Cursor) -> Result<Cursor, Reject> { 515 + if let Ok(input) = input.parse("c\"") { 516 + cooked_c_string(input) 517 + } else if let Ok(input) = input.parse("cr") { 518 + raw_c_string(input) 519 + } else { 520 + Err(Reject) 521 + } 522 + } 523 + 524 + fn raw_c_string(input: Cursor) -> Result<Cursor, Reject> { 525 + let (input, delimiter) = delimiter_of_raw_string(input)?; 526 + let mut bytes = input.bytes().enumerate(); 527 + while let Some((i, byte)) = bytes.next() { 528 + match byte { 529 + b'"' if input.rest[i + 1..].starts_with(delimiter) => { 530 + let rest = input.advance(i + 1 + delimiter.len()); 531 + return Ok(literal_suffix(rest)); 532 + } 533 + b'\r' => match bytes.next() { 534 + Some((_, b'\n')) => {} 535 + _ => break, 536 + }, 537 + b'\0' => break, 538 + _ => {} 539 + } 540 + } 541 + Err(Reject) 542 + } 543 + 544 + fn cooked_c_string(mut input: Cursor) -> Result<Cursor, Reject> { 545 + let mut chars = input.char_indices(); 546 + 547 + while let Some((i, ch)) = chars.next() { 548 + match ch { 549 + '"' => { 550 + let input = input.advance(i + 1); 551 + return Ok(literal_suffix(input)); 552 + } 553 + '\r' => match chars.next() { 554 + Some((_, '\n')) => {} 555 + _ => break, 556 + }, 557 + '\\' => match chars.next() { 558 + Some((_, 'x')) => { 559 + backslash_x_nonzero(&mut chars)?; 560 + } 561 + Some((_, 'n' | 'r' | 't' | '\\' | '\'' | '"')) => {} 562 + Some((_, 'u')) => { 563 + if backslash_u(&mut chars)? == '\0' { 564 + break; 565 + } 566 + } 567 + Some((newline, ch @ ('\n' | '\r'))) => { 568 + input = input.advance(newline + 1); 569 + trailing_backslash(&mut input, ch as u8)?; 570 + chars = input.char_indices(); 571 + } 572 + _ => break, 573 + }, 574 + '\0' => break, 575 + _ch => {} 576 + } 577 + } 578 + Err(Reject) 579 + } 580 + 581 + fn byte(input: Cursor) -> Result<Cursor, Reject> { 582 + let input = input.parse("b'")?; 583 + let mut bytes = input.bytes().enumerate(); 584 + let ok = match bytes.next().map(|(_, b)| b) { 585 + Some(b'\\') => match bytes.next().map(|(_, b)| b) { 586 + Some(b'x') => backslash_x_byte(&mut bytes).is_ok(), 587 + Some(b'n' | b'r' | b't' | b'\\' | b'0' | b'\'' | b'"') => true, 588 + _ => false, 589 + }, 590 + b => b.is_some(), 591 + }; 592 + if !ok { 593 + return Err(Reject); 594 + } 595 + let (offset, _) = bytes.next().ok_or(Reject)?; 596 + if !input.chars().as_str().is_char_boundary(offset) { 597 + return Err(Reject); 598 + } 599 + let input = input.advance(offset).parse("'")?; 600 + Ok(literal_suffix(input)) 601 + } 602 + 603 + fn character(input: Cursor) -> Result<Cursor, Reject> { 604 + let input = input.parse("'")?; 605 + let mut chars = input.char_indices(); 606 + let ok = match chars.next().map(|(_, ch)| ch) { 607 + Some('\\') => match chars.next().map(|(_, ch)| ch) { 608 + Some('x') => backslash_x_char(&mut chars).is_ok(), 609 + Some('u') => backslash_u(&mut chars).is_ok(), 610 + Some('n' | 'r' | 't' | '\\' | '0' | '\'' | '"') => true, 611 + _ => false, 612 + }, 613 + ch => ch.is_some(), 614 + }; 615 + if !ok { 616 + return Err(Reject); 617 + } 618 + let (idx, _) = chars.next().ok_or(Reject)?; 619 + let input = input.advance(idx).parse("'")?; 620 + Ok(literal_suffix(input)) 621 + } 622 + 623 + macro_rules! next_ch { 624 + ($chars:ident @ $pat:pat) => { 625 + match $chars.next() { 626 + Some((_, ch)) => match ch { 627 + $pat => ch, 628 + _ => return Err(Reject), 629 + }, 630 + None => return Err(Reject), 631 + } 632 + }; 633 + } 634 + 635 + fn backslash_x_char<I>(chars: &mut I) -> Result<(), Reject> 636 + where 637 + I: Iterator<Item = (usize, char)>, 638 + { 639 + next_ch!(chars @ '0'..='7'); 640 + next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); 641 + Ok(()) 642 + } 643 + 644 + fn backslash_x_byte<I>(chars: &mut I) -> Result<(), Reject> 645 + where 646 + I: Iterator<Item = (usize, u8)>, 647 + { 648 + next_ch!(chars @ b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F'); 649 + next_ch!(chars @ b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F'); 650 + Ok(()) 651 + } 652 + 653 + fn backslash_x_nonzero<I>(chars: &mut I) -> Result<(), Reject> 654 + where 655 + I: Iterator<Item = (usize, char)>, 656 + { 657 + let first = next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); 658 + let second = next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); 659 + if first == '0' && second == '0' { 660 + Err(Reject) 661 + } else { 662 + Ok(()) 663 + } 664 + } 665 + 666 + fn backslash_u<I>(chars: &mut I) -> Result<char, Reject> 667 + where 668 + I: Iterator<Item = (usize, char)>, 669 + { 670 + next_ch!(chars @ '{'); 671 + let mut value = 0; 672 + let mut len = 0; 673 + for (_, ch) in chars { 674 + let digit = match ch { 675 + '0'..='9' => ch as u8 - b'0', 676 + 'a'..='f' => 10 + ch as u8 - b'a', 677 + 'A'..='F' => 10 + ch as u8 - b'A', 678 + '_' if len > 0 => continue, 679 + '}' if len > 0 => return char::from_u32(value).ok_or(Reject), 680 + _ => break, 681 + }; 682 + if len == 6 { 683 + break; 684 + } 685 + value *= 0x10; 686 + value += u32::from(digit); 687 + len += 1; 688 + } 689 + Err(Reject) 690 + } 691 + 692 + fn trailing_backslash(input: &mut Cursor, mut last: u8) -> Result<(), Reject> { 693 + let mut whitespace = input.bytes().enumerate(); 694 + loop { 695 + if last == b'\r' && whitespace.next().map_or(true, |(_, b)| b != b'\n') { 696 + return Err(Reject); 697 + } 698 + match whitespace.next() { 699 + Some((_, b @ (b' ' | b'\t' | b'\n' | b'\r'))) => { 700 + last = b; 701 + } 702 + Some((offset, _)) => { 703 + *input = input.advance(offset); 704 + return Ok(()); 705 + } 706 + None => return Err(Reject), 707 + } 708 + } 709 + } 710 + 711 + fn float(input: Cursor) -> Result<Cursor, Reject> { 712 + let mut rest = float_digits(input)?; 713 + if let Some(ch) = rest.chars().next() { 714 + if is_ident_start(ch) { 715 + rest = ident_not_raw(rest)?.0; 716 + } 717 + } 718 + word_break(rest) 719 + } 720 + 721 + fn float_digits(input: Cursor) -> Result<Cursor, Reject> { 722 + let mut chars = input.chars().peekable(); 723 + match chars.next() { 724 + Some(ch) if '0' <= ch && ch <= '9' => {} 725 + _ => return Err(Reject), 726 + } 727 + 728 + let mut len = 1; 729 + let mut has_dot = false; 730 + let mut has_exp = false; 731 + while let Some(&ch) = chars.peek() { 732 + match ch { 733 + '0'..='9' | '_' => { 734 + chars.next(); 735 + len += 1; 736 + } 737 + '.' => { 738 + if has_dot { 739 + break; 740 + } 741 + chars.next(); 742 + if chars 743 + .peek() 744 + .map_or(false, |&ch| ch == '.' || is_ident_start(ch)) 745 + { 746 + return Err(Reject); 747 + } 748 + len += 1; 749 + has_dot = true; 750 + } 751 + 'e' | 'E' => { 752 + chars.next(); 753 + len += 1; 754 + has_exp = true; 755 + break; 756 + } 757 + _ => break, 758 + } 759 + } 760 + 761 + if !(has_dot || has_exp) { 762 + return Err(Reject); 763 + } 764 + 765 + if has_exp { 766 + let token_before_exp = if has_dot { 767 + Ok(input.advance(len - 1)) 768 + } else { 769 + Err(Reject) 770 + }; 771 + let mut has_sign = false; 772 + let mut has_exp_value = false; 773 + while let Some(&ch) = chars.peek() { 774 + match ch { 775 + '+' | '-' => { 776 + if has_exp_value { 777 + break; 778 + } 779 + if has_sign { 780 + return token_before_exp; 781 + } 782 + chars.next(); 783 + len += 1; 784 + has_sign = true; 785 + } 786 + '0'..='9' => { 787 + chars.next(); 788 + len += 1; 789 + has_exp_value = true; 790 + } 791 + '_' => { 792 + chars.next(); 793 + len += 1; 794 + } 795 + _ => break, 796 + } 797 + } 798 + if !has_exp_value { 799 + return token_before_exp; 800 + } 801 + } 802 + 803 + Ok(input.advance(len)) 804 + } 805 + 806 + fn int(input: Cursor) -> Result<Cursor, Reject> { 807 + let mut rest = digits(input)?; 808 + if let Some(ch) = rest.chars().next() { 809 + if is_ident_start(ch) { 810 + rest = ident_not_raw(rest)?.0; 811 + } 812 + } 813 + word_break(rest) 814 + } 815 + 816 + fn digits(mut input: Cursor) -> Result<Cursor, Reject> { 817 + let base = if input.starts_with("0x") { 818 + input = input.advance(2); 819 + 16 820 + } else if input.starts_with("0o") { 821 + input = input.advance(2); 822 + 8 823 + } else if input.starts_with("0b") { 824 + input = input.advance(2); 825 + 2 826 + } else { 827 + 10 828 + }; 829 + 830 + let mut len = 0; 831 + let mut empty = true; 832 + for b in input.bytes() { 833 + match b { 834 + b'0'..=b'9' => { 835 + let digit = (b - b'0') as u64; 836 + if digit >= base { 837 + return Err(Reject); 838 + } 839 + } 840 + b'a'..=b'f' => { 841 + let digit = 10 + (b - b'a') as u64; 842 + if digit >= base { 843 + break; 844 + } 845 + } 846 + b'A'..=b'F' => { 847 + let digit = 10 + (b - b'A') as u64; 848 + if digit >= base { 849 + break; 850 + } 851 + } 852 + b'_' => { 853 + if empty && base == 10 { 854 + return Err(Reject); 855 + } 856 + len += 1; 857 + continue; 858 + } 859 + _ => break, 860 + } 861 + len += 1; 862 + empty = false; 863 + } 864 + if empty { 865 + Err(Reject) 866 + } else { 867 + Ok(input.advance(len)) 868 + } 869 + } 870 + 871 + fn punct(input: Cursor) -> PResult<Punct> { 872 + let (rest, ch) = punct_char(input)?; 873 + if ch == '\'' { 874 + let (after_lifetime, _ident) = ident_any(rest)?; 875 + if after_lifetime.starts_with_char('\'') 876 + || (after_lifetime.starts_with_char('#') && !rest.starts_with("r#")) 877 + { 878 + Err(Reject) 879 + } else { 880 + Ok((rest, Punct::new('\'', Spacing::Joint))) 881 + } 882 + } else { 883 + let kind = match punct_char(rest) { 884 + Ok(_) => Spacing::Joint, 885 + Err(Reject) => Spacing::Alone, 886 + }; 887 + Ok((rest, Punct::new(ch, kind))) 888 + } 889 + } 890 + 891 + fn punct_char(input: Cursor) -> PResult<char> { 892 + if input.starts_with("//") || input.starts_with("/*") { 893 + // Do not accept `/` of a comment as a punct. 894 + return Err(Reject); 895 + } 896 + 897 + let mut chars = input.chars(); 898 + let first = match chars.next() { 899 + Some(ch) => ch, 900 + None => { 901 + return Err(Reject); 902 + } 903 + }; 904 + let recognized = "~!@#$%^&*-=+|;:,<.>/?'"; 905 + if recognized.contains(first) { 906 + Ok((input.advance(first.len_utf8()), first)) 907 + } else { 908 + Err(Reject) 909 + } 910 + } 911 + 912 + fn doc_comment<'a>(input: Cursor<'a>, trees: &mut TokenStreamBuilder) -> PResult<'a, ()> { 913 + #[cfg(span_locations)] 914 + let lo = input.off; 915 + let (rest, (comment, inner)) = doc_comment_contents(input)?; 916 + let fallback_span = Span { 917 + #[cfg(span_locations)] 918 + lo, 919 + #[cfg(span_locations)] 920 + hi: rest.off, 921 + }; 922 + let span = crate::Span::_new_fallback(fallback_span); 923 + 924 + let mut scan_for_bare_cr = comment; 925 + while let Some(cr) = scan_for_bare_cr.find('\r') { 926 + let rest = &scan_for_bare_cr[cr + 1..]; 927 + if !rest.starts_with('\n') { 928 + return Err(Reject); 929 + } 930 + scan_for_bare_cr = rest; 931 + } 932 + 933 + let mut pound = Punct::new('#', Spacing::Alone); 934 + pound.set_span(span); 935 + trees.push_token_from_parser(TokenTree::Punct(pound)); 936 + 937 + if inner { 938 + let mut bang = Punct::new('!', Spacing::Alone); 939 + bang.set_span(span); 940 + trees.push_token_from_parser(TokenTree::Punct(bang)); 941 + } 942 + 943 + let doc_ident = crate::Ident::_new_fallback(Ident::new_unchecked("doc", fallback_span)); 944 + let mut equal = Punct::new('=', Spacing::Alone); 945 + equal.set_span(span); 946 + let mut literal = crate::Literal::_new_fallback(Literal::string(comment)); 947 + literal.set_span(span); 948 + let mut bracketed = TokenStreamBuilder::with_capacity(3); 949 + bracketed.push_token_from_parser(TokenTree::Ident(doc_ident)); 950 + bracketed.push_token_from_parser(TokenTree::Punct(equal)); 951 + bracketed.push_token_from_parser(TokenTree::Literal(literal)); 952 + let group = Group::new(Delimiter::Bracket, bracketed.build()); 953 + let mut group = crate::Group::_new_fallback(group); 954 + group.set_span(span); 955 + trees.push_token_from_parser(TokenTree::Group(group)); 956 + 957 + Ok((rest, ())) 958 + } 959 + 960 + fn doc_comment_contents(input: Cursor) -> PResult<(&str, bool)> { 961 + if input.starts_with("//!") { 962 + let input = input.advance(3); 963 + let (input, s) = take_until_newline_or_eof(input); 964 + Ok((input, (s, true))) 965 + } else if input.starts_with("/*!") { 966 + let (input, s) = block_comment(input)?; 967 + Ok((input, (&s[3..s.len() - 2], true))) 968 + } else if input.starts_with("///") { 969 + let input = input.advance(3); 970 + if input.starts_with_char('/') { 971 + return Err(Reject); 972 + } 973 + let (input, s) = take_until_newline_or_eof(input); 974 + Ok((input, (s, false))) 975 + } else if input.starts_with("/**") && !input.rest[3..].starts_with('*') { 976 + let (input, s) = block_comment(input)?; 977 + Ok((input, (&s[3..s.len() - 2], false))) 978 + } else { 979 + Err(Reject) 980 + } 981 + } 982 + 983 + fn take_until_newline_or_eof(input: Cursor) -> (Cursor, &str) { 984 + let chars = input.char_indices(); 985 + 986 + for (i, ch) in chars { 987 + if ch == '\n' { 988 + return (input.advance(i), &input.rest[..i]); 989 + } else if ch == '\r' && input.rest[i + 1..].starts_with('\n') { 990 + return (input.advance(i + 1), &input.rest[..i]); 991 + } 992 + } 993 + 994 + (input.advance(input.len()), input.rest) 995 + }
+10
rust/proc-macro2/probe.rs
··· 1 + #![allow(dead_code)] 2 + 3 + #[cfg(proc_macro_span)] 4 + pub(crate) mod proc_macro_span; 5 + 6 + #[cfg(proc_macro_span_file)] 7 + pub(crate) mod proc_macro_span_file; 8 + 9 + #[cfg(proc_macro_span_location)] 10 + pub(crate) mod proc_macro_span_location;
+51
rust/proc-macro2/probe/proc_macro_span.rs
··· 1 + // This code exercises the surface area that we expect of Span's unstable API. 2 + // If the current toolchain is able to compile it, then proc-macro2 is able to 3 + // offer these APIs too. 4 + 5 + #![cfg_attr(procmacro2_build_probe, feature(proc_macro_span))] 6 + 7 + extern crate proc_macro; 8 + 9 + use core::ops::{Range, RangeBounds}; 10 + use proc_macro::{Literal, Span}; 11 + use std::path::PathBuf; 12 + 13 + pub fn byte_range(this: &Span) -> Range<usize> { 14 + this.byte_range() 15 + } 16 + 17 + pub fn start(this: &Span) -> Span { 18 + this.start() 19 + } 20 + 21 + pub fn end(this: &Span) -> Span { 22 + this.end() 23 + } 24 + 25 + pub fn line(this: &Span) -> usize { 26 + this.line() 27 + } 28 + 29 + pub fn column(this: &Span) -> usize { 30 + this.column() 31 + } 32 + 33 + pub fn file(this: &Span) -> String { 34 + this.file() 35 + } 36 + 37 + pub fn local_file(this: &Span) -> Option<PathBuf> { 38 + this.local_file() 39 + } 40 + 41 + pub fn join(this: &Span, other: Span) -> Option<Span> { 42 + this.join(other) 43 + } 44 + 45 + pub fn subspan<R: RangeBounds<usize>>(this: &Literal, range: R) -> Option<Span> { 46 + this.subspan(range) 47 + } 48 + 49 + // Include in sccache cache key. 50 + #[cfg(procmacro2_build_probe)] 51 + const _: Option<&str> = option_env!("RUSTC_BOOTSTRAP");
+14
rust/proc-macro2/probe/proc_macro_span_file.rs
··· 1 + // The subset of Span's API stabilized in Rust 1.88. 2 + 3 + extern crate proc_macro; 4 + 5 + use proc_macro::Span; 6 + use std::path::PathBuf; 7 + 8 + pub fn file(this: &Span) -> String { 9 + this.file() 10 + } 11 + 12 + pub fn local_file(this: &Span) -> Option<PathBuf> { 13 + this.local_file() 14 + }
+21
rust/proc-macro2/probe/proc_macro_span_location.rs
··· 1 + // The subset of Span's API stabilized in Rust 1.88. 2 + 3 + extern crate proc_macro; 4 + 5 + use proc_macro::Span; 6 + 7 + pub fn start(this: &Span) -> Span { 8 + this.start() 9 + } 10 + 11 + pub fn end(this: &Span) -> Span { 12 + this.end() 13 + } 14 + 15 + pub fn line(this: &Span) -> usize { 16 + this.line() 17 + } 18 + 19 + pub fn column(this: &Span) -> usize { 20 + this.column() 21 + }
+146
rust/proc-macro2/rcvec.rs
··· 1 + use alloc::rc::Rc; 2 + use alloc::vec; 3 + use core::mem; 4 + use core::panic::RefUnwindSafe; 5 + use core::slice; 6 + 7 + pub(crate) struct RcVec<T> { 8 + inner: Rc<Vec<T>>, 9 + } 10 + 11 + pub(crate) struct RcVecBuilder<T> { 12 + inner: Vec<T>, 13 + } 14 + 15 + pub(crate) struct RcVecMut<'a, T> { 16 + inner: &'a mut Vec<T>, 17 + } 18 + 19 + #[derive(Clone)] 20 + pub(crate) struct RcVecIntoIter<T> { 21 + inner: vec::IntoIter<T>, 22 + } 23 + 24 + impl<T> RcVec<T> { 25 + pub(crate) fn is_empty(&self) -> bool { 26 + self.inner.is_empty() 27 + } 28 + 29 + pub(crate) fn len(&self) -> usize { 30 + self.inner.len() 31 + } 32 + 33 + pub(crate) fn iter(&self) -> slice::Iter<T> { 34 + self.inner.iter() 35 + } 36 + 37 + pub(crate) fn make_mut(&mut self) -> RcVecMut<T> 38 + where 39 + T: Clone, 40 + { 41 + RcVecMut { 42 + inner: Rc::make_mut(&mut self.inner), 43 + } 44 + } 45 + 46 + pub(crate) fn get_mut(&mut self) -> Option<RcVecMut<T>> { 47 + let inner = Rc::get_mut(&mut self.inner)?; 48 + Some(RcVecMut { inner }) 49 + } 50 + 51 + pub(crate) fn make_owned(mut self) -> RcVecBuilder<T> 52 + where 53 + T: Clone, 54 + { 55 + let vec = if let Some(owned) = Rc::get_mut(&mut self.inner) { 56 + mem::take(owned) 57 + } else { 58 + Vec::clone(&self.inner) 59 + }; 60 + RcVecBuilder { inner: vec } 61 + } 62 + } 63 + 64 + impl<T> RcVecBuilder<T> { 65 + pub(crate) fn new() -> Self { 66 + RcVecBuilder { inner: Vec::new() } 67 + } 68 + 69 + pub(crate) fn with_capacity(cap: usize) -> Self { 70 + RcVecBuilder { 71 + inner: Vec::with_capacity(cap), 72 + } 73 + } 74 + 75 + pub(crate) fn push(&mut self, element: T) { 76 + self.inner.push(element); 77 + } 78 + 79 + pub(crate) fn extend(&mut self, iter: impl IntoIterator<Item = T>) { 80 + self.inner.extend(iter); 81 + } 82 + 83 + pub(crate) fn as_mut(&mut self) -> RcVecMut<T> { 84 + RcVecMut { 85 + inner: &mut self.inner, 86 + } 87 + } 88 + 89 + pub(crate) fn build(self) -> RcVec<T> { 90 + RcVec { 91 + inner: Rc::new(self.inner), 92 + } 93 + } 94 + } 95 + 96 + impl<'a, T> RcVecMut<'a, T> { 97 + pub(crate) fn push(&mut self, element: T) { 98 + self.inner.push(element); 99 + } 100 + 101 + pub(crate) fn extend(&mut self, iter: impl IntoIterator<Item = T>) { 102 + self.inner.extend(iter); 103 + } 104 + 105 + pub(crate) fn as_mut(&mut self) -> RcVecMut<T> { 106 + RcVecMut { inner: self.inner } 107 + } 108 + 109 + pub(crate) fn take(self) -> RcVecBuilder<T> { 110 + let vec = mem::take(self.inner); 111 + RcVecBuilder { inner: vec } 112 + } 113 + } 114 + 115 + impl<T> Clone for RcVec<T> { 116 + fn clone(&self) -> Self { 117 + RcVec { 118 + inner: Rc::clone(&self.inner), 119 + } 120 + } 121 + } 122 + 123 + impl<T> IntoIterator for RcVecBuilder<T> { 124 + type Item = T; 125 + type IntoIter = RcVecIntoIter<T>; 126 + 127 + fn into_iter(self) -> Self::IntoIter { 128 + RcVecIntoIter { 129 + inner: self.inner.into_iter(), 130 + } 131 + } 132 + } 133 + 134 + impl<T> Iterator for RcVecIntoIter<T> { 135 + type Item = T; 136 + 137 + fn next(&mut self) -> Option<Self::Item> { 138 + self.inner.next() 139 + } 140 + 141 + fn size_hint(&self) -> (usize, Option<usize>) { 142 + self.inner.size_hint() 143 + } 144 + } 145 + 146 + impl<T> RefUnwindSafe for RcVec<T> where T: RefUnwindSafe {}
+984
rust/proc-macro2/wrapper.rs
··· 1 + use crate::detection::inside_proc_macro; 2 + use crate::fallback::{self, FromStr2 as _}; 3 + #[cfg(span_locations)] 4 + use crate::location::LineColumn; 5 + #[cfg(proc_macro_span)] 6 + use crate::probe::proc_macro_span; 7 + #[cfg(all(span_locations, proc_macro_span_file))] 8 + use crate::probe::proc_macro_span_file; 9 + #[cfg(all(span_locations, proc_macro_span_location))] 10 + use crate::probe::proc_macro_span_location; 11 + use crate::{Delimiter, Punct, Spacing, TokenTree}; 12 + use core::fmt::{self, Debug, Display}; 13 + #[cfg(span_locations)] 14 + use core::ops::Range; 15 + use core::ops::RangeBounds; 16 + use std::ffi::CStr; 17 + #[cfg(span_locations)] 18 + use std::path::PathBuf; 19 + 20 + #[derive(Clone)] 21 + pub(crate) enum TokenStream { 22 + Compiler(DeferredTokenStream), 23 + Fallback(fallback::TokenStream), 24 + } 25 + 26 + // Work around https://github.com/rust-lang/rust/issues/65080. 27 + // In `impl Extend<TokenTree> for TokenStream` which is used heavily by quote, 28 + // we hold on to the appended tokens and do proc_macro::TokenStream::extend as 29 + // late as possible to batch together consecutive uses of the Extend impl. 30 + #[derive(Clone)] 31 + pub(crate) struct DeferredTokenStream { 32 + stream: proc_macro::TokenStream, 33 + extra: Vec<proc_macro::TokenTree>, 34 + } 35 + 36 + pub(crate) enum LexError { 37 + Compiler(proc_macro::LexError), 38 + Fallback(fallback::LexError), 39 + 40 + // Rustc was supposed to return a LexError, but it panicked instead. 41 + // https://github.com/rust-lang/rust/issues/58736 42 + CompilerPanic, 43 + } 44 + 45 + #[cold] 46 + fn mismatch(line: u32) -> ! { 47 + #[cfg(procmacro2_backtrace)] 48 + { 49 + let backtrace = std::backtrace::Backtrace::force_capture(); 50 + panic!("compiler/fallback mismatch L{}\n\n{}", line, backtrace) 51 + } 52 + #[cfg(not(procmacro2_backtrace))] 53 + { 54 + panic!("compiler/fallback mismatch L{}", line) 55 + } 56 + } 57 + 58 + impl DeferredTokenStream { 59 + fn new(stream: proc_macro::TokenStream) -> Self { 60 + DeferredTokenStream { 61 + stream, 62 + extra: Vec::new(), 63 + } 64 + } 65 + 66 + fn is_empty(&self) -> bool { 67 + self.stream.is_empty() && self.extra.is_empty() 68 + } 69 + 70 + fn evaluate_now(&mut self) { 71 + // If-check provides a fast short circuit for the common case of `extra` 72 + // being empty, which saves a round trip over the proc macro bridge. 73 + // Improves macro expansion time in winrt by 6% in debug mode. 74 + if !self.extra.is_empty() { 75 + self.stream.extend(self.extra.drain(..)); 76 + } 77 + } 78 + 79 + fn into_token_stream(mut self) -> proc_macro::TokenStream { 80 + self.evaluate_now(); 81 + self.stream 82 + } 83 + } 84 + 85 + impl TokenStream { 86 + pub(crate) fn new() -> Self { 87 + if inside_proc_macro() { 88 + TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::new())) 89 + } else { 90 + TokenStream::Fallback(fallback::TokenStream::new()) 91 + } 92 + } 93 + 94 + pub(crate) fn from_str_checked(src: &str) -> Result<Self, LexError> { 95 + if inside_proc_macro() { 96 + Ok(TokenStream::Compiler(DeferredTokenStream::new( 97 + proc_macro::TokenStream::from_str_checked(src)?, 98 + ))) 99 + } else { 100 + Ok(TokenStream::Fallback( 101 + fallback::TokenStream::from_str_checked(src)?, 102 + )) 103 + } 104 + } 105 + 106 + pub(crate) fn is_empty(&self) -> bool { 107 + match self { 108 + TokenStream::Compiler(tts) => tts.is_empty(), 109 + TokenStream::Fallback(tts) => tts.is_empty(), 110 + } 111 + } 112 + 113 + fn unwrap_nightly(self) -> proc_macro::TokenStream { 114 + match self { 115 + TokenStream::Compiler(s) => s.into_token_stream(), 116 + TokenStream::Fallback(_) => mismatch(line!()), 117 + } 118 + } 119 + 120 + fn unwrap_stable(self) -> fallback::TokenStream { 121 + match self { 122 + TokenStream::Compiler(_) => mismatch(line!()), 123 + TokenStream::Fallback(s) => s, 124 + } 125 + } 126 + } 127 + 128 + impl Display for TokenStream { 129 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 130 + match self { 131 + TokenStream::Compiler(tts) => Display::fmt(&tts.clone().into_token_stream(), f), 132 + TokenStream::Fallback(tts) => Display::fmt(tts, f), 133 + } 134 + } 135 + } 136 + 137 + impl From<proc_macro::TokenStream> for TokenStream { 138 + fn from(inner: proc_macro::TokenStream) -> Self { 139 + TokenStream::Compiler(DeferredTokenStream::new(inner)) 140 + } 141 + } 142 + 143 + impl From<TokenStream> for proc_macro::TokenStream { 144 + fn from(inner: TokenStream) -> Self { 145 + match inner { 146 + TokenStream::Compiler(inner) => inner.into_token_stream(), 147 + TokenStream::Fallback(inner) => { 148 + proc_macro::TokenStream::from_str_unchecked(&inner.to_string()) 149 + } 150 + } 151 + } 152 + } 153 + 154 + impl From<fallback::TokenStream> for TokenStream { 155 + fn from(inner: fallback::TokenStream) -> Self { 156 + TokenStream::Fallback(inner) 157 + } 158 + } 159 + 160 + // Assumes inside_proc_macro(). 161 + fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree { 162 + match token { 163 + TokenTree::Group(tt) => proc_macro::TokenTree::Group(tt.inner.unwrap_nightly()), 164 + TokenTree::Punct(tt) => { 165 + let spacing = match tt.spacing() { 166 + Spacing::Joint => proc_macro::Spacing::Joint, 167 + Spacing::Alone => proc_macro::Spacing::Alone, 168 + }; 169 + let mut punct = proc_macro::Punct::new(tt.as_char(), spacing); 170 + punct.set_span(tt.span().inner.unwrap_nightly()); 171 + proc_macro::TokenTree::Punct(punct) 172 + } 173 + TokenTree::Ident(tt) => proc_macro::TokenTree::Ident(tt.inner.unwrap_nightly()), 174 + TokenTree::Literal(tt) => proc_macro::TokenTree::Literal(tt.inner.unwrap_nightly()), 175 + } 176 + } 177 + 178 + impl From<TokenTree> for TokenStream { 179 + fn from(token: TokenTree) -> Self { 180 + if inside_proc_macro() { 181 + TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::from( 182 + into_compiler_token(token), 183 + ))) 184 + } else { 185 + TokenStream::Fallback(fallback::TokenStream::from(token)) 186 + } 187 + } 188 + } 189 + 190 + impl FromIterator<TokenTree> for TokenStream { 191 + fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self { 192 + if inside_proc_macro() { 193 + TokenStream::Compiler(DeferredTokenStream::new( 194 + trees.into_iter().map(into_compiler_token).collect(), 195 + )) 196 + } else { 197 + TokenStream::Fallback(trees.into_iter().collect()) 198 + } 199 + } 200 + } 201 + 202 + impl FromIterator<TokenStream> for TokenStream { 203 + fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self { 204 + let mut streams = streams.into_iter(); 205 + match streams.next() { 206 + Some(TokenStream::Compiler(mut first)) => { 207 + first.evaluate_now(); 208 + first.stream.extend(streams.map(|s| match s { 209 + TokenStream::Compiler(s) => s.into_token_stream(), 210 + TokenStream::Fallback(_) => mismatch(line!()), 211 + })); 212 + TokenStream::Compiler(first) 213 + } 214 + Some(TokenStream::Fallback(mut first)) => { 215 + first.extend(streams.map(|s| match s { 216 + TokenStream::Fallback(s) => s, 217 + TokenStream::Compiler(_) => mismatch(line!()), 218 + })); 219 + TokenStream::Fallback(first) 220 + } 221 + None => TokenStream::new(), 222 + } 223 + } 224 + } 225 + 226 + impl Extend<TokenTree> for TokenStream { 227 + fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, stream: I) { 228 + match self { 229 + TokenStream::Compiler(tts) => { 230 + // Here is the reason for DeferredTokenStream. 231 + for token in stream { 232 + tts.extra.push(into_compiler_token(token)); 233 + } 234 + } 235 + TokenStream::Fallback(tts) => tts.extend(stream), 236 + } 237 + } 238 + } 239 + 240 + impl Extend<TokenStream> for TokenStream { 241 + fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) { 242 + match self { 243 + TokenStream::Compiler(tts) => { 244 + tts.evaluate_now(); 245 + tts.stream 246 + .extend(streams.into_iter().map(TokenStream::unwrap_nightly)); 247 + } 248 + TokenStream::Fallback(tts) => { 249 + tts.extend(streams.into_iter().map(TokenStream::unwrap_stable)); 250 + } 251 + } 252 + } 253 + } 254 + 255 + impl Debug for TokenStream { 256 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 257 + match self { 258 + TokenStream::Compiler(tts) => Debug::fmt(&tts.clone().into_token_stream(), f), 259 + TokenStream::Fallback(tts) => Debug::fmt(tts, f), 260 + } 261 + } 262 + } 263 + 264 + impl LexError { 265 + pub(crate) fn span(&self) -> Span { 266 + match self { 267 + LexError::Compiler(_) | LexError::CompilerPanic => Span::call_site(), 268 + LexError::Fallback(e) => Span::Fallback(e.span()), 269 + } 270 + } 271 + } 272 + 273 + impl From<proc_macro::LexError> for LexError { 274 + fn from(e: proc_macro::LexError) -> Self { 275 + LexError::Compiler(e) 276 + } 277 + } 278 + 279 + impl From<fallback::LexError> for LexError { 280 + fn from(e: fallback::LexError) -> Self { 281 + LexError::Fallback(e) 282 + } 283 + } 284 + 285 + impl Debug for LexError { 286 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 287 + match self { 288 + LexError::Compiler(e) => Debug::fmt(e, f), 289 + LexError::Fallback(e) => Debug::fmt(e, f), 290 + LexError::CompilerPanic => { 291 + let fallback = fallback::LexError::call_site(); 292 + Debug::fmt(&fallback, f) 293 + } 294 + } 295 + } 296 + } 297 + 298 + impl Display for LexError { 299 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 300 + match self { 301 + LexError::Compiler(e) => Display::fmt(e, f), 302 + LexError::Fallback(e) => Display::fmt(e, f), 303 + LexError::CompilerPanic => { 304 + let fallback = fallback::LexError::call_site(); 305 + Display::fmt(&fallback, f) 306 + } 307 + } 308 + } 309 + } 310 + 311 + #[derive(Clone)] 312 + pub(crate) enum TokenTreeIter { 313 + Compiler(proc_macro::token_stream::IntoIter), 314 + Fallback(fallback::TokenTreeIter), 315 + } 316 + 317 + impl IntoIterator for TokenStream { 318 + type Item = TokenTree; 319 + type IntoIter = TokenTreeIter; 320 + 321 + fn into_iter(self) -> TokenTreeIter { 322 + match self { 323 + TokenStream::Compiler(tts) => { 324 + TokenTreeIter::Compiler(tts.into_token_stream().into_iter()) 325 + } 326 + TokenStream::Fallback(tts) => TokenTreeIter::Fallback(tts.into_iter()), 327 + } 328 + } 329 + } 330 + 331 + impl Iterator for TokenTreeIter { 332 + type Item = TokenTree; 333 + 334 + fn next(&mut self) -> Option<TokenTree> { 335 + let token = match self { 336 + TokenTreeIter::Compiler(iter) => iter.next()?, 337 + TokenTreeIter::Fallback(iter) => return iter.next(), 338 + }; 339 + Some(match token { 340 + proc_macro::TokenTree::Group(tt) => { 341 + TokenTree::Group(crate::Group::_new(Group::Compiler(tt))) 342 + } 343 + proc_macro::TokenTree::Punct(tt) => { 344 + let spacing = match tt.spacing() { 345 + proc_macro::Spacing::Joint => Spacing::Joint, 346 + proc_macro::Spacing::Alone => Spacing::Alone, 347 + }; 348 + let mut o = Punct::new(tt.as_char(), spacing); 349 + o.set_span(crate::Span::_new(Span::Compiler(tt.span()))); 350 + TokenTree::Punct(o) 351 + } 352 + proc_macro::TokenTree::Ident(s) => { 353 + TokenTree::Ident(crate::Ident::_new(Ident::Compiler(s))) 354 + } 355 + proc_macro::TokenTree::Literal(l) => { 356 + TokenTree::Literal(crate::Literal::_new(Literal::Compiler(l))) 357 + } 358 + }) 359 + } 360 + 361 + fn size_hint(&self) -> (usize, Option<usize>) { 362 + match self { 363 + TokenTreeIter::Compiler(tts) => tts.size_hint(), 364 + TokenTreeIter::Fallback(tts) => tts.size_hint(), 365 + } 366 + } 367 + } 368 + 369 + #[derive(Copy, Clone)] 370 + pub(crate) enum Span { 371 + Compiler(proc_macro::Span), 372 + Fallback(fallback::Span), 373 + } 374 + 375 + impl Span { 376 + pub(crate) fn call_site() -> Self { 377 + if inside_proc_macro() { 378 + Span::Compiler(proc_macro::Span::call_site()) 379 + } else { 380 + Span::Fallback(fallback::Span::call_site()) 381 + } 382 + } 383 + 384 + pub(crate) fn mixed_site() -> Self { 385 + if inside_proc_macro() { 386 + Span::Compiler(proc_macro::Span::mixed_site()) 387 + } else { 388 + Span::Fallback(fallback::Span::mixed_site()) 389 + } 390 + } 391 + 392 + #[cfg(super_unstable)] 393 + pub(crate) fn def_site() -> Self { 394 + if inside_proc_macro() { 395 + Span::Compiler(proc_macro::Span::def_site()) 396 + } else { 397 + Span::Fallback(fallback::Span::def_site()) 398 + } 399 + } 400 + 401 + pub(crate) fn resolved_at(&self, other: Span) -> Span { 402 + match (self, other) { 403 + (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.resolved_at(b)), 404 + (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.resolved_at(b)), 405 + (Span::Compiler(_), Span::Fallback(_)) => mismatch(line!()), 406 + (Span::Fallback(_), Span::Compiler(_)) => mismatch(line!()), 407 + } 408 + } 409 + 410 + pub(crate) fn located_at(&self, other: Span) -> Span { 411 + match (self, other) { 412 + (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.located_at(b)), 413 + (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.located_at(b)), 414 + (Span::Compiler(_), Span::Fallback(_)) => mismatch(line!()), 415 + (Span::Fallback(_), Span::Compiler(_)) => mismatch(line!()), 416 + } 417 + } 418 + 419 + pub(crate) fn unwrap(self) -> proc_macro::Span { 420 + match self { 421 + Span::Compiler(s) => s, 422 + Span::Fallback(_) => panic!("proc_macro::Span is only available in procedural macros"), 423 + } 424 + } 425 + 426 + #[cfg(span_locations)] 427 + pub(crate) fn byte_range(&self) -> Range<usize> { 428 + match self { 429 + #[cfg(proc_macro_span)] 430 + Span::Compiler(s) => proc_macro_span::byte_range(s), 431 + #[cfg(not(proc_macro_span))] 432 + Span::Compiler(_) => 0..0, 433 + Span::Fallback(s) => s.byte_range(), 434 + } 435 + } 436 + 437 + #[cfg(span_locations)] 438 + pub(crate) fn start(&self) -> LineColumn { 439 + match self { 440 + #[cfg(proc_macro_span_location)] 441 + Span::Compiler(s) => LineColumn { 442 + line: proc_macro_span_location::line(s), 443 + column: proc_macro_span_location::column(s).saturating_sub(1), 444 + }, 445 + #[cfg(not(proc_macro_span_location))] 446 + Span::Compiler(_) => LineColumn { line: 0, column: 0 }, 447 + Span::Fallback(s) => s.start(), 448 + } 449 + } 450 + 451 + #[cfg(span_locations)] 452 + pub(crate) fn end(&self) -> LineColumn { 453 + match self { 454 + #[cfg(proc_macro_span_location)] 455 + Span::Compiler(s) => { 456 + let end = proc_macro_span_location::end(s); 457 + LineColumn { 458 + line: proc_macro_span_location::line(&end), 459 + column: proc_macro_span_location::column(&end).saturating_sub(1), 460 + } 461 + } 462 + #[cfg(not(proc_macro_span_location))] 463 + Span::Compiler(_) => LineColumn { line: 0, column: 0 }, 464 + Span::Fallback(s) => s.end(), 465 + } 466 + } 467 + 468 + #[cfg(span_locations)] 469 + pub(crate) fn file(&self) -> String { 470 + match self { 471 + #[cfg(proc_macro_span_file)] 472 + Span::Compiler(s) => proc_macro_span_file::file(s), 473 + #[cfg(not(proc_macro_span_file))] 474 + Span::Compiler(_) => "<token stream>".to_owned(), 475 + Span::Fallback(s) => s.file(), 476 + } 477 + } 478 + 479 + #[cfg(span_locations)] 480 + pub(crate) fn local_file(&self) -> Option<PathBuf> { 481 + match self { 482 + #[cfg(proc_macro_span_file)] 483 + Span::Compiler(s) => proc_macro_span_file::local_file(s), 484 + #[cfg(not(proc_macro_span_file))] 485 + Span::Compiler(_) => None, 486 + Span::Fallback(s) => s.local_file(), 487 + } 488 + } 489 + 490 + pub(crate) fn join(&self, other: Span) -> Option<Span> { 491 + let ret = match (self, other) { 492 + #[cfg(proc_macro_span)] 493 + (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(proc_macro_span::join(a, b)?), 494 + (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.join(b)?), 495 + _ => return None, 496 + }; 497 + Some(ret) 498 + } 499 + 500 + #[cfg(super_unstable)] 501 + pub(crate) fn eq(&self, other: &Span) -> bool { 502 + match (self, other) { 503 + (Span::Compiler(a), Span::Compiler(b)) => a.eq(b), 504 + (Span::Fallback(a), Span::Fallback(b)) => a.eq(b), 505 + _ => false, 506 + } 507 + } 508 + 509 + pub(crate) fn source_text(&self) -> Option<String> { 510 + match self { 511 + #[cfg(not(no_source_text))] 512 + Span::Compiler(s) => s.source_text(), 513 + #[cfg(no_source_text)] 514 + Span::Compiler(_) => None, 515 + Span::Fallback(s) => s.source_text(), 516 + } 517 + } 518 + 519 + fn unwrap_nightly(self) -> proc_macro::Span { 520 + match self { 521 + Span::Compiler(s) => s, 522 + Span::Fallback(_) => mismatch(line!()), 523 + } 524 + } 525 + } 526 + 527 + impl From<proc_macro::Span> for crate::Span { 528 + fn from(proc_span: proc_macro::Span) -> Self { 529 + crate::Span::_new(Span::Compiler(proc_span)) 530 + } 531 + } 532 + 533 + impl From<fallback::Span> for Span { 534 + fn from(inner: fallback::Span) -> Self { 535 + Span::Fallback(inner) 536 + } 537 + } 538 + 539 + impl Debug for Span { 540 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 541 + match self { 542 + Span::Compiler(s) => Debug::fmt(s, f), 543 + Span::Fallback(s) => Debug::fmt(s, f), 544 + } 545 + } 546 + } 547 + 548 + pub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) { 549 + match span { 550 + Span::Compiler(s) => { 551 + debug.field("span", &s); 552 + } 553 + Span::Fallback(s) => fallback::debug_span_field_if_nontrivial(debug, s), 554 + } 555 + } 556 + 557 + #[derive(Clone)] 558 + pub(crate) enum Group { 559 + Compiler(proc_macro::Group), 560 + Fallback(fallback::Group), 561 + } 562 + 563 + impl Group { 564 + pub(crate) fn new(delimiter: Delimiter, stream: TokenStream) -> Self { 565 + match stream { 566 + TokenStream::Compiler(tts) => { 567 + let delimiter = match delimiter { 568 + Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis, 569 + Delimiter::Bracket => proc_macro::Delimiter::Bracket, 570 + Delimiter::Brace => proc_macro::Delimiter::Brace, 571 + Delimiter::None => proc_macro::Delimiter::None, 572 + }; 573 + Group::Compiler(proc_macro::Group::new(delimiter, tts.into_token_stream())) 574 + } 575 + TokenStream::Fallback(stream) => { 576 + Group::Fallback(fallback::Group::new(delimiter, stream)) 577 + } 578 + } 579 + } 580 + 581 + pub(crate) fn delimiter(&self) -> Delimiter { 582 + match self { 583 + Group::Compiler(g) => match g.delimiter() { 584 + proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis, 585 + proc_macro::Delimiter::Bracket => Delimiter::Bracket, 586 + proc_macro::Delimiter::Brace => Delimiter::Brace, 587 + proc_macro::Delimiter::None => Delimiter::None, 588 + }, 589 + Group::Fallback(g) => g.delimiter(), 590 + } 591 + } 592 + 593 + pub(crate) fn stream(&self) -> TokenStream { 594 + match self { 595 + Group::Compiler(g) => TokenStream::Compiler(DeferredTokenStream::new(g.stream())), 596 + Group::Fallback(g) => TokenStream::Fallback(g.stream()), 597 + } 598 + } 599 + 600 + pub(crate) fn span(&self) -> Span { 601 + match self { 602 + Group::Compiler(g) => Span::Compiler(g.span()), 603 + Group::Fallback(g) => Span::Fallback(g.span()), 604 + } 605 + } 606 + 607 + pub(crate) fn span_open(&self) -> Span { 608 + match self { 609 + Group::Compiler(g) => Span::Compiler(g.span_open()), 610 + Group::Fallback(g) => Span::Fallback(g.span_open()), 611 + } 612 + } 613 + 614 + pub(crate) fn span_close(&self) -> Span { 615 + match self { 616 + Group::Compiler(g) => Span::Compiler(g.span_close()), 617 + Group::Fallback(g) => Span::Fallback(g.span_close()), 618 + } 619 + } 620 + 621 + pub(crate) fn set_span(&mut self, span: Span) { 622 + match (self, span) { 623 + (Group::Compiler(g), Span::Compiler(s)) => g.set_span(s), 624 + (Group::Fallback(g), Span::Fallback(s)) => g.set_span(s), 625 + (Group::Compiler(_), Span::Fallback(_)) => mismatch(line!()), 626 + (Group::Fallback(_), Span::Compiler(_)) => mismatch(line!()), 627 + } 628 + } 629 + 630 + fn unwrap_nightly(self) -> proc_macro::Group { 631 + match self { 632 + Group::Compiler(g) => g, 633 + Group::Fallback(_) => mismatch(line!()), 634 + } 635 + } 636 + } 637 + 638 + impl From<fallback::Group> for Group { 639 + fn from(g: fallback::Group) -> Self { 640 + Group::Fallback(g) 641 + } 642 + } 643 + 644 + impl Display for Group { 645 + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 646 + match self { 647 + Group::Compiler(group) => Display::fmt(group, formatter), 648 + Group::Fallback(group) => Display::fmt(group, formatter), 649 + } 650 + } 651 + } 652 + 653 + impl Debug for Group { 654 + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 655 + match self { 656 + Group::Compiler(group) => Debug::fmt(group, formatter), 657 + Group::Fallback(group) => Debug::fmt(group, formatter), 658 + } 659 + } 660 + } 661 + 662 + #[derive(Clone)] 663 + pub(crate) enum Ident { 664 + Compiler(proc_macro::Ident), 665 + Fallback(fallback::Ident), 666 + } 667 + 668 + impl Ident { 669 + #[track_caller] 670 + pub(crate) fn new_checked(string: &str, span: Span) -> Self { 671 + match span { 672 + Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new(string, s)), 673 + Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_checked(string, s)), 674 + } 675 + } 676 + 677 + #[track_caller] 678 + pub(crate) fn new_raw_checked(string: &str, span: Span) -> Self { 679 + match span { 680 + Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new_raw(string, s)), 681 + Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_raw_checked(string, s)), 682 + } 683 + } 684 + 685 + pub(crate) fn span(&self) -> Span { 686 + match self { 687 + Ident::Compiler(t) => Span::Compiler(t.span()), 688 + Ident::Fallback(t) => Span::Fallback(t.span()), 689 + } 690 + } 691 + 692 + pub(crate) fn set_span(&mut self, span: Span) { 693 + match (self, span) { 694 + (Ident::Compiler(t), Span::Compiler(s)) => t.set_span(s), 695 + (Ident::Fallback(t), Span::Fallback(s)) => t.set_span(s), 696 + (Ident::Compiler(_), Span::Fallback(_)) => mismatch(line!()), 697 + (Ident::Fallback(_), Span::Compiler(_)) => mismatch(line!()), 698 + } 699 + } 700 + 701 + fn unwrap_nightly(self) -> proc_macro::Ident { 702 + match self { 703 + Ident::Compiler(s) => s, 704 + Ident::Fallback(_) => mismatch(line!()), 705 + } 706 + } 707 + } 708 + 709 + impl From<fallback::Ident> for Ident { 710 + fn from(inner: fallback::Ident) -> Self { 711 + Ident::Fallback(inner) 712 + } 713 + } 714 + 715 + impl PartialEq for Ident { 716 + fn eq(&self, other: &Ident) -> bool { 717 + match (self, other) { 718 + (Ident::Compiler(t), Ident::Compiler(o)) => t.to_string() == o.to_string(), 719 + (Ident::Fallback(t), Ident::Fallback(o)) => t == o, 720 + (Ident::Compiler(_), Ident::Fallback(_)) => mismatch(line!()), 721 + (Ident::Fallback(_), Ident::Compiler(_)) => mismatch(line!()), 722 + } 723 + } 724 + } 725 + 726 + impl<T> PartialEq<T> for Ident 727 + where 728 + T: ?Sized + AsRef<str>, 729 + { 730 + fn eq(&self, other: &T) -> bool { 731 + let other = other.as_ref(); 732 + match self { 733 + Ident::Compiler(t) => t.to_string() == other, 734 + Ident::Fallback(t) => t == other, 735 + } 736 + } 737 + } 738 + 739 + impl Display for Ident { 740 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 741 + match self { 742 + Ident::Compiler(t) => Display::fmt(t, f), 743 + Ident::Fallback(t) => Display::fmt(t, f), 744 + } 745 + } 746 + } 747 + 748 + impl Debug for Ident { 749 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 750 + match self { 751 + Ident::Compiler(t) => Debug::fmt(t, f), 752 + Ident::Fallback(t) => Debug::fmt(t, f), 753 + } 754 + } 755 + } 756 + 757 + #[derive(Clone)] 758 + pub(crate) enum Literal { 759 + Compiler(proc_macro::Literal), 760 + Fallback(fallback::Literal), 761 + } 762 + 763 + macro_rules! suffixed_numbers { 764 + ($($name:ident => $kind:ident,)*) => ($( 765 + pub(crate) fn $name(n: $kind) -> Literal { 766 + if inside_proc_macro() { 767 + Literal::Compiler(proc_macro::Literal::$name(n)) 768 + } else { 769 + Literal::Fallback(fallback::Literal::$name(n)) 770 + } 771 + } 772 + )*) 773 + } 774 + 775 + macro_rules! unsuffixed_integers { 776 + ($($name:ident => $kind:ident,)*) => ($( 777 + pub(crate) fn $name(n: $kind) -> Literal { 778 + if inside_proc_macro() { 779 + Literal::Compiler(proc_macro::Literal::$name(n)) 780 + } else { 781 + Literal::Fallback(fallback::Literal::$name(n)) 782 + } 783 + } 784 + )*) 785 + } 786 + 787 + impl Literal { 788 + pub(crate) fn from_str_checked(repr: &str) -> Result<Self, LexError> { 789 + if inside_proc_macro() { 790 + let literal = proc_macro::Literal::from_str_checked(repr)?; 791 + Ok(Literal::Compiler(literal)) 792 + } else { 793 + let literal = fallback::Literal::from_str_checked(repr)?; 794 + Ok(Literal::Fallback(literal)) 795 + } 796 + } 797 + 798 + pub(crate) unsafe fn from_str_unchecked(repr: &str) -> Self { 799 + if inside_proc_macro() { 800 + Literal::Compiler(proc_macro::Literal::from_str_unchecked(repr)) 801 + } else { 802 + Literal::Fallback(unsafe { fallback::Literal::from_str_unchecked(repr) }) 803 + } 804 + } 805 + 806 + suffixed_numbers! { 807 + u8_suffixed => u8, 808 + u16_suffixed => u16, 809 + u32_suffixed => u32, 810 + u64_suffixed => u64, 811 + u128_suffixed => u128, 812 + usize_suffixed => usize, 813 + i8_suffixed => i8, 814 + i16_suffixed => i16, 815 + i32_suffixed => i32, 816 + i64_suffixed => i64, 817 + i128_suffixed => i128, 818 + isize_suffixed => isize, 819 + 820 + f32_suffixed => f32, 821 + f64_suffixed => f64, 822 + } 823 + 824 + unsuffixed_integers! { 825 + u8_unsuffixed => u8, 826 + u16_unsuffixed => u16, 827 + u32_unsuffixed => u32, 828 + u64_unsuffixed => u64, 829 + u128_unsuffixed => u128, 830 + usize_unsuffixed => usize, 831 + i8_unsuffixed => i8, 832 + i16_unsuffixed => i16, 833 + i32_unsuffixed => i32, 834 + i64_unsuffixed => i64, 835 + i128_unsuffixed => i128, 836 + isize_unsuffixed => isize, 837 + } 838 + 839 + pub(crate) fn f32_unsuffixed(f: f32) -> Literal { 840 + if inside_proc_macro() { 841 + Literal::Compiler(proc_macro::Literal::f32_unsuffixed(f)) 842 + } else { 843 + Literal::Fallback(fallback::Literal::f32_unsuffixed(f)) 844 + } 845 + } 846 + 847 + pub(crate) fn f64_unsuffixed(f: f64) -> Literal { 848 + if inside_proc_macro() { 849 + Literal::Compiler(proc_macro::Literal::f64_unsuffixed(f)) 850 + } else { 851 + Literal::Fallback(fallback::Literal::f64_unsuffixed(f)) 852 + } 853 + } 854 + 855 + pub(crate) fn string(string: &str) -> Literal { 856 + if inside_proc_macro() { 857 + Literal::Compiler(proc_macro::Literal::string(string)) 858 + } else { 859 + Literal::Fallback(fallback::Literal::string(string)) 860 + } 861 + } 862 + 863 + pub(crate) fn character(ch: char) -> Literal { 864 + if inside_proc_macro() { 865 + Literal::Compiler(proc_macro::Literal::character(ch)) 866 + } else { 867 + Literal::Fallback(fallback::Literal::character(ch)) 868 + } 869 + } 870 + 871 + pub(crate) fn byte_character(byte: u8) -> Literal { 872 + if inside_proc_macro() { 873 + Literal::Compiler({ 874 + #[cfg(not(no_literal_byte_character))] 875 + { 876 + proc_macro::Literal::byte_character(byte) 877 + } 878 + 879 + #[cfg(no_literal_byte_character)] 880 + { 881 + let fallback = fallback::Literal::byte_character(byte); 882 + proc_macro::Literal::from_str_unchecked(&fallback.repr) 883 + } 884 + }) 885 + } else { 886 + Literal::Fallback(fallback::Literal::byte_character(byte)) 887 + } 888 + } 889 + 890 + pub(crate) fn byte_string(bytes: &[u8]) -> Literal { 891 + if inside_proc_macro() { 892 + Literal::Compiler(proc_macro::Literal::byte_string(bytes)) 893 + } else { 894 + Literal::Fallback(fallback::Literal::byte_string(bytes)) 895 + } 896 + } 897 + 898 + pub(crate) fn c_string(string: &CStr) -> Literal { 899 + if inside_proc_macro() { 900 + Literal::Compiler({ 901 + #[cfg(not(no_literal_c_string))] 902 + { 903 + proc_macro::Literal::c_string(string) 904 + } 905 + 906 + #[cfg(no_literal_c_string)] 907 + { 908 + let fallback = fallback::Literal::c_string(string); 909 + proc_macro::Literal::from_str_unchecked(&fallback.repr) 910 + } 911 + }) 912 + } else { 913 + Literal::Fallback(fallback::Literal::c_string(string)) 914 + } 915 + } 916 + 917 + pub(crate) fn span(&self) -> Span { 918 + match self { 919 + Literal::Compiler(lit) => Span::Compiler(lit.span()), 920 + Literal::Fallback(lit) => Span::Fallback(lit.span()), 921 + } 922 + } 923 + 924 + pub(crate) fn set_span(&mut self, span: Span) { 925 + match (self, span) { 926 + (Literal::Compiler(lit), Span::Compiler(s)) => lit.set_span(s), 927 + (Literal::Fallback(lit), Span::Fallback(s)) => lit.set_span(s), 928 + (Literal::Compiler(_), Span::Fallback(_)) => mismatch(line!()), 929 + (Literal::Fallback(_), Span::Compiler(_)) => mismatch(line!()), 930 + } 931 + } 932 + 933 + pub(crate) fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> { 934 + match self { 935 + #[cfg(proc_macro_span)] 936 + Literal::Compiler(lit) => proc_macro_span::subspan(lit, range).map(Span::Compiler), 937 + #[cfg(not(proc_macro_span))] 938 + Literal::Compiler(_lit) => None, 939 + Literal::Fallback(lit) => lit.subspan(range).map(Span::Fallback), 940 + } 941 + } 942 + 943 + fn unwrap_nightly(self) -> proc_macro::Literal { 944 + match self { 945 + Literal::Compiler(s) => s, 946 + Literal::Fallback(_) => mismatch(line!()), 947 + } 948 + } 949 + } 950 + 951 + impl From<fallback::Literal> for Literal { 952 + fn from(s: fallback::Literal) -> Self { 953 + Literal::Fallback(s) 954 + } 955 + } 956 + 957 + impl Display for Literal { 958 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 959 + match self { 960 + Literal::Compiler(t) => Display::fmt(t, f), 961 + Literal::Fallback(t) => Display::fmt(t, f), 962 + } 963 + } 964 + } 965 + 966 + impl Debug for Literal { 967 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 968 + match self { 969 + Literal::Compiler(t) => Debug::fmt(t, f), 970 + Literal::Fallback(t) => Debug::fmt(t, f), 971 + } 972 + } 973 + } 974 + 975 + #[cfg(span_locations)] 976 + pub(crate) fn invalidate_current_thread_spans() { 977 + if inside_proc_macro() { 978 + panic!( 979 + "proc_macro2::extra::invalidate_current_thread_spans is not available in procedural macros" 980 + ); 981 + } else { 982 + crate::fallback::invalidate_current_thread_spans(); 983 + } 984 + }